Присвоение аргументу fn
просто делает этот идентификатор указателем на анонимную функцию, foo
во внешней области не затрагивается.
Когда вы передаете объект в качестве аргумента, можно сказать, что «ссылки передаются по значению». Присвоение просто заменяет местоположение, к которому относится идентификатор fn
.
Вот как работает стратегия оценки в 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
нам требуется базовый объект и имя свойства , функции, объявленные в глобальном контексте выполнения, связаны как свойства Глобальный объект , поэтому мы можем переназначить его значение таким образом.
Строка fnChanger(this, 'foo');
должна выполняться также в глобальной области видимости, ей будет передано значение this
(которое относится к глобальному объекту в этой области) и имя свойства, позволяющее сделать присвоение GlobalObject.foo
идентификатор.
Если бы этот код был внутри функции, мы никак не могли бы получить базовый объект , потому что в этом «контексте выполнения кода функции» объявления функций (также объявления переменных и формальные параметры функции) связаны как свойства недоступного объекта , называемого Переменным Объектом (цепочка этих Переменных Объектов, образует Цепь Области), и если бы это было так, единственным обходным решением было бы использование eval
.
Дополнительная информация: