为什么 'self' 在原型的成员函数中可用?

Why is 'self' available in a prototype's member function?

我经常看到并使用 self 作为数据成员来保证对所有嵌套范围内的根对象的正确访问:

function Foo() {
    var self = this; // Common design pattern
}

但是,我不明白为什么在下面的代码片段中定义 self(参见 this jsfiddle):

function Foo() {
}

Foo.prototype.foo = function() {
    // Returns 'object'!  Why is 'self' defined?
    console.log("typeof self = " + typeof self);
}

var f = new Foo();
f.foo(); // Prints "typeof self = object"

谁能解释一下为什么 self 在函数的 prototype 对象上定义的函数中可用。

self 是全局 window 对象上的 属性,因此不需要使用前缀 window。由于 window 是一个对象,这就是控制台吐出的内容,但是 console.log 行可以在 self 未被重新定义为其他含义的任何地方,并且会给出相同的输出。

当您看到开发人员声明了一个名为 self 的变量时,他们正在为标识符创建一个更本地化的定义,并且 它会在此期间隐藏全局自身范围。

示例:

// In the global scope:
console.log(self);  // window

function foo(){
  // this declaration will hide the global self with a local version
  // only good for this function
  var self = this;  // or whatever

  console.log(self);  // Depends on how foo is invoked
}

如果您修改示例代码,稍微修改为:

function Foo() {
}

Foo.prototype.foo = function() {
    // Returns 'object'!  Why is 'self' defined?
    console.log(self); // <-- not typeof self
}

var f = new Foo();
f.foo(); // Prints window

顺便说一下,这就是为什么开发人员通常不会使用 self 这个词,而是使用 that:

 var that = this;