没有黑客攻击,私有JavaScript函数无法访问'this'对象?

Nic*_*ick 7 javascript private this

我正在研究一个项目一段时间,试图找出我做错了什么,当我最终将"错误"缩小到下面的代码不能按预期工作的事实时:

function Alpha()
    {
    this.onion = 'onion';

    function Beta()
        {
        alert(this.onion);
        }

    Beta();
    }

alpha1 = new Alpha();
// Alerts 'undefined'
Run Code Online (Sandbox Code Playgroud)

但是,如果我将代码更改为:

function Alpha()
    {
    var self = this;
    this.onion = 'onion';

    function Beta()
        {
        alert(self.onion);
        }

    Beta();
    }

alpha1 = new Alpha();
// Alerts 'onion'
Run Code Online (Sandbox Code Playgroud)

它像我期望的那样工作.在浪费了我生命中的大部分时间之后,任何人都可以解释为什么它会像这样工作吗?

CMS*_*CMS 10

这样工作是因为每个函数都关联了自己的执行上下文.

但是还有其他方法可以做到这一点,例如:

使用callapply调用函数:

function Alpha() {
  this.onion = 'onion';

  function Beta() {
    alert(this.onion);
  }

  Beta.call(this);
}

var alpha1 = new Alpha();
// Alerts 'onion'
Run Code Online (Sandbox Code Playgroud)

新的ECMAScript第5版标准,介绍了一种持久化函数上下文Function.prototype.bind方法,方法:

function Alpha() {
  this.onion = 'onion';

  var Beta = function () {
    alert(this.onion);
  }.bind(this);

  Beta();
}

var alpha1 = new Alpha();
// Alerts 'onion'
Run Code Online (Sandbox Code Playgroud)

我们可以说Beta函数是绑定的,无论你如何调用它,它的this值都将是完整的.

此方法尚未得到广泛支持,目前只有IE9pre3包含它,但您可以包含一个实现以使其现在正常工作.

现在让我详细说明一下如何this工作:

this值存在于每个执行上下文中,并且在进行函数调用时隐式设置函数代码,该值根据引用的形式确定.

在您的示例中,当您调用时Beta();,由于它没有绑定到任何对象,我们可以说引用没有基础对象,然后,该this值将引用全局对象.

当您调用绑定为对象属性的函数时会发生其他情况,例如:

var obj = {
  foo: function () { return this === obj;}
};
obj.foo(); // true
Run Code Online (Sandbox Code Playgroud)

如您所见,被调用的引用obj.bar();包含一个基础对象,它是obj,并且this被调用函数内的值将引用它.

注意:引用类型是一个抽象概念,为语言实现目的而定义,您可以在规范中查看详细信息.

this隐式设置值的第三种情况是,当您使用new运算符时,它将引用从其构造函数的原型继承的新创建的对象:

function Foo () {
  return this; // `this` is implicitly returned when a function is called 
}              // with `new`, this line is included only to make it obvious

var foo = new Foo();
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true
Run Code Online (Sandbox Code Playgroud)


Lau*_*ves 7

来自JavaScript:The Definitive Guide,第5版(犀牛书):

当函数作为函数而不是作为方法调用时, this关键字引用全局对象.令人困惑的是,即使在作为方法调用的包含方法中调用嵌套函数(作为函数)也是如此:this 关键字在包含函数中有一个值,但(违反直觉)是指在体内的全局对象嵌套函数.

请注意,这this是关键字,而不是变量或属性名称.JavaScript语法不允许您为其分配值this.

这里要注意两件事:

  1. this 不是变量,因此正常的闭包捕获规则不适用.
  2. this每个函数调用都会"反弹",无论是作为方法,还是正常的函数调用,还是通过new.由于您正在进行正常的函数调用(在调用Beta时),this因此被绑定到"全局对象".