Javascript:使用其他功能重新分配功能

Aus*_*yde 6 javascript closures function pass-by-reference

假设我有这两个功能:

function fnChanger(fn) {
    fn = function() { sys.print('Changed!'); }
}
function foo() {
    sys.print('Unchanged');
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我打电话foo(),我看到Unchanged,正如预期的那样.但是,如果我fnChanger先打电话,我仍然会看到Unchanged:

fnChanger(foo);
foo(); //Unchanged
Run Code Online (Sandbox Code Playgroud)

现在,我认为这是因为foo没有fnChanger通过引用传递,但我可能是错的.

为什么不fnChangerfoo印刷Changed!
此外,如何fnChangerfoo没有太多凌乱的语法的情况下进行更改?

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

CMS*_*CMS 5

fn参数的赋值只是使该标识符指向匿名函数,foo在外部作用域中不受影响.

当您将对象作为参数传递时,可以说"引用按值传递".赋值只是替换fn标识符引用的位置.

这就是评估策略在JavaScript中的工作方式.

就在fnChanger函数赋值之前,两个标识符global foofnargument指向同一个函数对象:

                ---------------------------------------------
    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(); // Changed!
Run Code Online (Sandbox Code Playgroud)

上面的方法是有效的,因为在fnChanger函数中,我们需要一个基础对象和一个属性名称,在全局执行上下文中声明的函数被绑定为Global对象的属性,因此我们可以用这种方式重新赋值.

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

如果该代码在函数内部,则我们无法获得基础对象,因为在此"函数代码执行上下文"中,函数声明(变量声明和函数形式参数也)被绑定为不可访问对象的属性,称为变量对象(这些变量对象的链,形成范围链),如果是这种情况,唯一的解决方法是使用eval.

更多信息: