javascript - 了解 Javascript 调用函数与返回函数但稍后执行函数之间的区别

标签 javascript prototype scope this

我试图理解 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;fnWoofdog 分离 - 它没有语境。因此,上下文和 this 关键字默认为 window。由于 window 没有 bark 属性,您会得到 undefined

如果你给窗口一个树皮属性:

window.bark = "Arf";

然后您的代码将起作用(尽管是错误的):

fnWoof(); // "Arf"

要使其按预期工作,您可以传入上下文显式:

fnWoof.call(dog);

关于javascript - 了解 Javascript 调用函数与返回函数但稍后执行函数之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4643049/

相关文章:

javascript - TamperMonkey - 不同子域上的脚本之间的消息

javascript - 如何正确使用html脚本模板

c - 头文件中的静态存储类

javascript - 为什么JavaScript中的 "this"说是隐式参数?

javascript - 使用 Ruby 和 Javascript 创建 div 时出现问题

javascript - 为什么当我记录一个函数时它只打印函数而不是完整的函数对象?

javascript - 如何检查变量是否是 ES6 类声明?

javascript - 如何克隆一个构造函数,以便它构造一个原始类型的副本,其行为与原始类型一样,但有自己的原型(prototype)?

c++ - 变量名与函数名相同,给出编译器错误...为什么?

c++ - 当我调用方法 C++ 时对象恢复为 Null