Рассмотрите этот код JavaScript:
var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();
При выполнении этого кода я получаю "A". Действительно ли это поведение является частью спецификации JavaScript, и я могу полагаться на него?
Да, это ожидается и задумано.
Ваш вопрос в основном таков: ссылается ли foo
на bar
как указатель или ссылка на другом языке?
Ответ отрицательный: значение из bar
на момент назначения назначен foo
.
я немного опаздываю здесь, но я думал, что буду давать ответ так или иначе и конкретизировать что-то.
лучше не думать с точки зрения указателей и ссылок памяти при обсуждении внутренностей JavaScript (или ECMAScript) при контакте со спецификациями. Переменные являются записями среды внутренне и сохранены и сосланы по имени, не адрес памяти. Что ваш оператор присваивания делает, внутренне и дизайном, ищет имя записи среды (или "нечто" или "панель") и присваивает значение той записи.
Так,
var bar = function () { alert("A"); }
присваивается, среда записывают "панель" значение (анонимная функция).
var foo = bar;
внутренне вызовы GetValue ("панель"), которая получает значение, связанное с рекордной "панелью", и затем связывает то значение с рекордным "нечто". Следовательно, впоследствии исходное значение панели может все еще использоваться, поскольку это теперь связано с нечто.
, поскольку ссылки JavaScript последовательностью и не адресом памяти точно, почему можно сделать вещи как это:
someObject["someProperty"]
, который ищет значение на основе имени свойства.
Да, это правильное поведение.
//create variable bar and assign a function to it
var bar = function () { alert("A"); }
//assign value of bar to the newly created variable foo
var foo = bar;
//assign a new function to the variable bar
//since foo and bar are not pointers, value of foo doesn't change
bar = function () { alert("B"); };
//call the function stored in foo
foo();
Это назначение переменной безымянной функции, а не указателя на функцию
-121--1082621-Да, вы создали указатель на исходную функцию "A". При переназначении строки выполняется переназначение , но все еще остаются ссылки только на старую функцию.
Поэтому, чтобы ответить на ваш вопрос, вы можете положиться на него.
-121--1082622-Да, нет ничего особенного в том, что переменные ссылаются на функции, нет никакого наложения.
var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1
Вы назначаете значение анонимной функции переменной, а не указателю.
Если вы хотите поиграть с указателями, вы можете использовать объекты, которые передаются по ссылке, а не копировать.
Вот несколько примеров:
«obj2» - это ссылка на «obj1», вы изменяете «obj2», а «obj1» изменяется. Он выдаст предупреждение false
.
var obj1 = {prop:true},
obj2 = obj1;
obj2.prop = false;
alert(obj1.prop);
«prop» указывает на свойство, которое не является объектом, «prop» - не указатель на этот объект, а его копия. Если вы измените "prop", "obj1" не изменится. Он выдаст предупреждение true
var obj1 = {prop:true},
prop = obj1.prop;
prop = false;
alert(obj1.prop);
«obj2» - это ссылка на свойство «subObj» объекта «obj1». если "obj2" изменяется, "obj1" изменяется. Он выдаст предупреждение false
.
var obj1 = {subObj:{prop:true}},
obj2 = obj1.subObj;
obj2.prop = false;
alert(obj1.subObj.prop);
Это не указатели функций (и в JS изначально нет указателей). Функции в JS могут быть анонимными и являются объектами первого класса. Отсюда
function () { alert("A"); }
создается анонимная функция, которая при выполнении выдает сигнал "A";
var bar = function () { alert("A"); };
назначаем эту функцию на bar;
var foo = bar;
назначаем foo на bar, который является функцией "A".
bar = function () { alert("B"); };
перепривязать bar к анонимной функции "B". Это не повлияет на foo или другую функцию "A".
foo();
Вызовите функцию, хранящуюся в foo, которая является функцией "A".
На самом деле в языках, где есть точки функций, например, в C, это также не повлияет на foo
. Я не знаю, откуда вы взяли идею получить "B" при переназначении.
void A(void) { printf("A\n"); }
void B(void) { printf("B\n"); }
typedef void(*fptr_t)(void);
fptr_t foo = A;
fptr_t bar = foo;
bar = B;
foo(); // should print "A"
Это присвоение переменной безымянной функции, а не указатель на функцию
Да, вы создали указатель на исходную функцию "A". Когда вы переназначаете bar, вы переназначаете его, но вы все еще оставляете любые ссылки на старую функцию.
Так что, отвечая на ваш вопрос, да, вы можете полагаться на это.