我正在尝试了解foo.bar()
和var fn = foo.bar; fn();
之间的区别
我整理了一个小例子,但我不完全理解为什么失败的人实际上会失败。
var Dog = function() {
this.bark = "Arf";
};
Dog.prototype.woof = function() {
$('ul').append('<li>'+ this.bark +'</li>');
};
var dog = new Dog();
// works, obviously
dog.woof();
// works
(dog.woof)();
// FAILS
var fnWoof = dog.woof;
fnWoof();
// works
setTimeout(function() {
dog.woof();
}, 0);
// FAILS
setTimeout(dog.woof, 0);
产生:
在JSFiddle上:http://jsfiddle.net/D6Vdg/1/
因此,似乎关闭一个函数会导致其删除其上下文。好的。但是,为什么
(dog.woof)();
起作用呢?弄清楚这里发生了什么,这一切都令人困惑。显然有一些我不了解的核心语义。
最佳答案
问题出在上下文和this
关键字上。
函数并不是天生就“属于”对象。例如,我可以创建一个cat对象,并将woof函数复制到以下位置:
var cat = {
bark: "meow",
woof = Dog.prototype.woof
};
现在
cat.woof
将给我“喵”声。由于要复制和重新分配的功能具有这种灵活性,因此var fnWoof = dog.woof;
将fnWoof
与dog
解除关联-它没有上下文。因此,上下文以及this
关键字默认为window
。由于window
没有bark
属性,因此得到undefined
。如果给窗口树皮属性:
window.bark = "Arf";
然后您的代码将起作用(尽管有误):
fnWoof(); // "Arf"
为了使其按预期工作,您可以显式传递上下文:
fnWoof.call(dog);