为什么'this'没有采取正确的范围

Why is 'this' not taking on the correct scope

本文关键字:范围 this 为什么      更新时间:2023-09-26

好吧,我知道有上千个关于Javascript中this范围的奇怪线程(这让人怀疑该语言是否设计良好)-但我仍然无法解释'这个':

//works
function Cat() { 
 this.theCatName = "Mistigri"; 
 function meow() {alert(this.theCatName + " meow") }; 
 this.meow = meow }
}
var MyCat = new Cat()
MyCat.meow() 
//works
function Cat() { 
this.theCatName = "Mistigri"; 
function meow() {alert(this.theCatName + " meow") }; 
this.meow = function() { alert(this.theCatName + " meow") }
}
var MyCat = new Cat()
MyCat.meow() 
//works
function Cat() { 
this.theCatName = "Mistigri"; 
function meow() {alert(this.theCatName + " meow") }; 
Cat.prototype.meow = function() { alert(this.theCatName + " meow") }
}
var MyCat = new Cat()
MyCat.meow() 
//doesn't work
function Cat() { 
this.theCatName = "Mistigri"; 
function meow() {alert(this.theCatName + " meow") }; 
this.meow = function() { meow() } }
}
var MyCat = new Cat()
MyCat.meow() 
//doesn't work
function Cat() { 
this.theCatName = "Mistigri"; 
function meow() {alert(this.theCatName + " meow") }; 
Cat.prototype.meow = function() { meow() } }
}
var MyCat = new Cat()
MyCat.meow() 

现在我的理解是,在后两种情况下,Cat.prototype.meowthis.meow是匿名函数,碰巧调用了喵(),这是Cat()的内部函数-但this的上下文显然是指函数内部的猫-它发生了什么?

这是一个半规范的答案:参见如何在回调中访问正确的this/context ?但是对于"this"的上下文实际上是什么,它只做了以下说明:

this(又名"context")是每个函数和中的一个特殊关键字它的值只取决于函数是如何被调用的,而不是如何/何时/在哪里定义的。它不受词汇范围的影响,和其他变量一样

当你调用一个对象的方法时,它只有当你作为对象的成员调用它时才有效,如果你得到对函数的引用或作为常规函数调用它,上下文不是对象。只有你调用函数的方式决定了上下文,上下文不是继承的,所以如果你从一个方法调用一个函数,它只是一个普通的函数调用。

的例子:

function Dog() {
  function bark() {}
  this.bark = bark;
  this.barkThrice() {
    bark(); // function call; context = window
    this.bark(); // method call; context = the object
    var b = this.bark;
    b(); // function call; context = window
  }
}

要将函数作为对象的方法调用,需要使用call方法(或bindapply)来设置调用的上下文:

function Cat() { 
  this.theCatName = "Mistigri"; 
  function meow() { alert(this.theCatName + " meow"); } 
  this.meow = function() { meow.call(this); };
}
var MyCat = new Cat();
MyCat.meow();

演示:http://jsfiddle.net/k6W9K/

我希望这对你有帮助:在函数内声明的变量不能在该函数外访问。在函数中定义的变量可以被它的嵌套函数访问。

function Cat() {
    // public var exist on the Cat instance: accesible from outside the Cat constructor
    this.theCatName = "Mistigri";
    // public function exist on the Cat instance
    // has access to all variables defined in the Cat constructor (_theCateName and _meow)
    // and all variables and methods defined on 'this'
    // this reference to a Cat Instance
    this.meow = function() {
        alert(this.theCatName);
        _meow();
    }
    // private var only accessible within the Cat constructor.
    var _theCateName = "_Mistigri"
    // private function only accessible within the Cat constructor.
    function _meow() {
        // _meow is defined as closure in the Cat constructor
        // In the function _meow 'this' is a reference to the scope from where the Cat function / constructor was applied (the window object in this case)
        alert(this.theCatName + " meow " + _theCateName); // outputs: undefined meow _Mistigri
    };
}
var MyCat = new Cat()
MyCat.meow()
alert (MyCat.theCatName)// outouts: Mistigri