分配给fn
参数只是使该标识符指向匿名函数,foo
在外部范围内不受影响。
当您将对象作为参数传递时,可以说“引用是按值传递的”。该分配只是替换了所在的位置fn
标识符指的是。
就是这样的评估策略 http://en.wikipedia.org/wiki/Evaluation_strategy在 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(); // Changed!
上面的方法会起作用,因为在fnChanger
函数,我们需要一个基础对象 and a 属性名称,在全局执行上下文中声明的函数被绑定为全局对象,因此我们可以用这种方式重新分配它的值。
线路fnChanger(this, 'foo');
也应该在全局范围内执行,它将传递this
值(引用此范围内的 Global 对象)和属性名称,允许您对GlobalObject.foo
标识符。
如果该代码位于函数内部,我们就无法获得基础对象,因为在这个“函数代码执行上下文”中,函数声明(还有变量声明和函数形参)被绑定为 a 的属性不可访问的对象,称为变量对象(这些变量对象的链,形成作用域链),如果是这种情况,唯一的解决方法是使用eval
.
更多信息:
- ECMA-262-3 详细信息。第8章评估策略。 http://dmitrysoshnikov.com/ecmascript/chapter-8-evaluation-strategy/