gpt4 book ai didi

javascript - 引用匿名函数与命名函数的属性

转载 作者:行者123 更新时间:2023-11-30 15:27:20 24 4
gpt4 key购买 nike

阅读 John Resig 的 Learning Advanced Javascript , 我遇到了两张我不完全理解的幻灯片。

幻灯片 #13 - 引用作为匿名函数的属性。第二个断言失败。

var ninja = { 
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); // PASS

var samurai = { yell: ninja.yell };
var ninja = null;

try {
samurai.yell(4);
} catch(e){
assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); // FAIL
}

幻灯片 #14 - 引用作为已定义函数的属性。第二个断言通过。

var ninja = { 
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); // PASS

var samurai = { yell: ninja.yell };
var ninja = {};
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." ); // PASS

此处唯一的区别是 yell 是幻灯片 14 中的命名函数。为什么即使在设置原始对象后,对定义为命名函数的属性的引用仍然存在 (ninja) 到一个新对象(甚至是 null)?

最佳答案

The only difference here is that yell is a named function in slide 14.

不,这不是唯一的区别,也不是最重要的区别(尽管它与重要的区别有关)。

在第一个中,注意 ninja.yell 是如何定义的:

var ninja = { 
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
// ----------------^^^^^^^^^^^^^^^
}
};

它在自身内部明确使用了 ninja.yell。因此调用它会查找变量 ninja,然后尝试查找 yell 作为 ninja 的属性。

将其与第二个示例中的定义进行比较:

var ninja = { 
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
// ----------------^^^^^^^^^
}
};

yell 不再使用变量 ninja,它仅使用自身的范围内标识符(通过命名函数表达式为函数命名而创建的标识符).

这就是为什么在第一个例子中 ninja 被清空的原因:

var ninja = null; 

...第一个开始失败;你不能在 null 上查找 yell

但是当 ninaj 在第二个中被替换时(我不明白为什么 John 在这两种情况下都没有使用 null,但无论如何):

var ninja = {};

...yell 不在乎,因为它不使用ninja


旁注:从 ES2015 开始,yell 的两个版本都不是匿名函数,即使第一个版本是使用匿名函数表达式创建的。在 ES2015 中,函数可以根据上下文获取其名称,其中一种获取名称的方法是在对象初始值设定项中分配给对象属性。不过,这对解决这个问题没有帮助,因为名称不是函数内的范围内标识符,就像您使用命名函数表达式时那样。

关于javascript - 引用匿名函数与命名函数的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42766177/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com