Присвоение указателя функции JavaScript

Рассмотрите этот код JavaScript:

var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();

При выполнении этого кода я получаю "A". Действительно ли это поведение является частью спецификации JavaScript, и я могу полагаться на него?

47
задан niaher 24 February 2010 в 12:53
поделиться

8 ответов

Да, это ожидается и задумано.

Ваш вопрос в основном таков: ссылается ли foo на bar как указатель или ссылка на другом языке?

Ответ отрицательный: значение из bar на момент назначения назначен foo .

38
ответ дан 26 November 2019 в 19:18
поделиться

я немного опаздываю здесь, но я думал, что буду давать ответ так или иначе и конкретизировать что-то.

лучше не думать с точки зрения указателей и ссылок памяти при обсуждении внутренностей JavaScript (или ECMAScript) при контакте со спецификациями. Переменные являются записями среды внутренне и сохранены и сосланы по имени, не адрес памяти. Что ваш оператор присваивания делает, внутренне и дизайном, ищет имя записи среды (или "нечто" или "панель") и присваивает значение той записи.

Так,

var bar = function () { alert("A"); }

присваивается, среда записывают "панель" значение (анонимная функция).

var foo = bar;

внутренне вызовы GetValue ("панель"), которая получает значение, связанное с рекордной "панелью", и затем связывает то значение с рекордным "нечто". Следовательно, впоследствии исходное значение панели может все еще использоваться, поскольку это теперь связано с нечто.

, поскольку ссылки JavaScript последовательностью и не адресом памяти точно, почему можно сделать вещи как это:

someObject["someProperty"]

, который ищет значение на основе имени свойства.

19
ответ дан 26 November 2019 в 19:18
поделиться

Да, это правильное поведение.

//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();
3
ответ дан 26 November 2019 в 19:18
поделиться

Это назначение переменной безымянной функции, а не указателя на функцию

-121--1082621-

Да, вы создали указатель на исходную функцию "A". При переназначении строки выполняется переназначение , но все еще остаются ссылки только на старую функцию.

Поэтому, чтобы ответить на ваш вопрос, вы можете положиться на него.

-121--1082622-

Да, нет ничего особенного в том, что переменные ссылаются на функции, нет никакого наложения.

var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1
5
ответ дан 26 November 2019 в 19:18
поделиться

Вы назначаете значение анонимной функции переменной, а не указателю.
Если вы хотите поиграть с указателями, вы можете использовать объекты, которые передаются по ссылке, а не копировать.

Вот несколько примеров:

«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);
5
ответ дан 26 November 2019 в 19:18
поделиться

Это не указатели функций (и в 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"
2
ответ дан 26 November 2019 в 19:18
поделиться

Это присвоение переменной безымянной функции, а не указатель на функцию

1
ответ дан 26 November 2019 в 19:18
поделиться

Да, вы создали указатель на исходную функцию "A". Когда вы переназначаете bar, вы переназначаете его, но вы все еще оставляете любые ссылки на старую функцию.

Так что, отвечая на ваш вопрос, да, вы можете полагаться на это.

1
ответ дан 26 November 2019 в 19:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: