Javascript:使用另一个函数重新分配函数 [英] Javascript: Re-assigning a function with another function

查看:182
本文介绍了Javascript:使用另一个函数重新分配函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这两个函数:

  function fnChanger(fn){
fn = function {sys.print('Changed!'); }
}
function foo(){
sys.print('Unchanged');
}



现在,如果我调用 foo code>,我看到未改变,如预期。但是,如果我先调用 fnChanger ,我仍然会看到 Unchanged

  fnChanger(foo); 
foo(); // Unchanged

现在,我假设这是因为 foo 未通过引用传递给 fnChanger ,但我可能是错误的。



为什么 fnChanger 不更改 foo 以打印已更改!

此外,如何获取 fnChanger 更改 foo ,而不会有太多的混乱语法?



PS:我使用node.js来测试所有这些东西,所以这是 sys.print 的来源。

解决方案

fn 参数的赋值只是使该标识符指向



当你将一个对象作为参数传递时,一个匿名函数, foo 可以说引用通过值。



这是 ://en.wikipedia.org/wiki/Evaluation_strategyrel =nofollow> 评估策略 适用于JavaScript。



fnChanger 函数中的赋值之前,两个标识符全局 foo fn 参数,指向同一个函数对象:

 
---------- -----------------------------------
foo -----> | function foo { sys.print('Un changed!'); } |
---------------------------------------------
^
|
fn -------------

作业完成后, fn 将简单指向新函数:

 
------------ ---------------------------------
foo -----> | function foo {sys.print('Unchanged!'); } |
---------------------------------------------

---------------------------------------
fn ------> function {sys.print('Changed!'); } |
---------------------------------------


好吧,假设 foo 是全局范围中的函数,可以这样做:

  function fnChanger(obj,name) {
obj [name] = function(){sys.print('Changed!'); };
}

function foo(){
sys.print('Unchanged');
}

fnChanger(this,'foo');
foo(); //改变了!

上述操作将起作用,因为在 fnChanger 函数,我们需要一个基础对象属性名称,在全局执行上下文中声明的函数被绑定为全局对象的属性我们可以用这种方式重新赋值。



fnChanger(this,'foo'); 应该也在全局范围中执行,它将传递这个值(它引用此范围中的全局对象)和属性名称,允许您进行赋值到 GlobalObject.foo 标识符。



如果该代码在函数内部,因为在这个功能代码执行上下文中,函数声明(变量声明和函数形式参数)也被作为不可访问对象的属性绑定,称为变量对象(这些变量对象的链,形成Scope链),如果是这种情况,唯一的解决方法是使用 eval



更多信息:




Let's say I have these two functions:

function fnChanger(fn) {
    fn = function() { sys.print('Changed!'); }
}
function foo() {
    sys.print('Unchanged');
}

Now, if I call foo(), I see Unchanged, as expected. However, if I call fnChanger first, I still see Unchanged:

fnChanger(foo);
foo(); //Unchanged

Now, I assume this is because foo is not being passed to fnChanger by reference, but I may be wrong.

Why does fnChanger not change foo to print Changed!?
Furthermore, how can I get fnChanger to change foo without too much messy syntax?

PS: I'm using node.js to test all this stuff, so that's where the sys.print comes from.

解决方案

The assignment to the fn argument just makes that identifier to point to the anonymous function, foo in the outer scope is not affected.

When you pass an object as an argument, one can say "references are passed by value". The assignment just replaces the location where the fn identifier refers to.

That's how the evaluation strategy works in JavaScript.

Just before the assignment in the fnChanger functions, the two identifiers, the global foo and the fn argument, point to the same function object:

                ---------------------------------------------
    foo ----->  |function foo { sys.print('Un changed!'); } |
                ---------------------------------------------
                   ^
                   |
    fn -------------

After the assignment, fn will simply point to the new function:

                ---------------------------------------------
    foo ----->  | function foo { sys.print('Unchanged!'); } |
                ---------------------------------------------

                ---------------------------------------
    fn ------>  | function { sys.print('Changed!'); } |
                ---------------------------------------

How could you change it?

Well, assuming that foo is a function in the global scope, you could do something like this:

function fnChanger(obj, name) {
    obj[name] = function() { sys.print('Changed!'); };
}

function foo() {
    sys.print('Unchanged');
}

fnChanger(this, 'foo');
foo(); // Changed!

The above will work because in the fnChanger function, we require a base object and a property name, functions declared in the global execution context are bound as properties of the Global object, therefore we can re-assign its value in that way.

The line fnChanger(this, 'foo'); should be executed also in the Global scope, it will pass the this value (which refers to the Global object in this scope) and a property name, allowing you to make an assignment to the GlobalObject.foo identifier.

If that code were inside a function, there is no way we can get a base object, because in this "Function Code Execution Context", function declarations (variable declarations and function formal parameters also) are bound as properties of a non-accessible object, called the Variable Object (a chain of these Variable Objects, forms the Scope Chain), and if it were the case, the only workaround would be to use eval.

More info:

这篇关于Javascript:使用另一个函数重新分配函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆