javascript - 如果没有 hack,就不能在私有(private) JavaScript 函数中访问“this”对象吗?

标签 javascript this private

我在一个项目上工作了一段时间,试图找出我做错了什么,当我最终将“错误”缩小到以下代码无法按我预期工作的事实时:

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

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

    Beta();
    }

alpha1 = new Alpha();
// Alerts 'undefined'

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

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

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

    Beta();
    }

alpha1 = new Alpha();
// Alerts 'onion'

它的工作方式与我预期的一样。在浪费了我生命的大部分时间之后,谁能解释为什么它会这样工作?

最佳答案

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

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

使用 callapply调用函数:

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

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

  Beta.call(this);
}

var alpha1 = new Alpha();
// Alerts 'onion'

新的 ECMAScript 第 5 版标准引入了一种方法来持久化函数contextFunction.prototype.bind方法:

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

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

  Beta();
}

var alpha1 = new Alpha();
// Alerts 'onion'

我们可以说Beta 函数是绑定(bind) 的,无论您如何调用它,它的this 值都是完整的。

这个方法还没有被广泛支持,目前只有IE9pre3包含,但是你可以包含an implementation让它现在工作。

现在让我详细说明this是如何工作的:

this 值存在于每个 execution context 上,并且对于函数代码是在进行函数调用时隐式设置的,其值取决于引用的形成方式。

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

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

var obj = {
  foo: function () { return this === obj;}
};
obj.foo(); // true

如您所见,被调用的引用 obj.bar(); 包含一个基础对象,即 obj,以及 this 被调用函数中的值将引用它。

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

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

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

关于javascript - 如果没有 hack,就不能在私有(private) JavaScript 函数中访问“this”对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3274387/

相关文章:

javascript - 如何将样式表应用于动态创建的元素?

java - 使用递归创建幂方法

Swift 4 - 扩展中的私有(private)方法

javascript - ReactJS ReactCSSTransitionGroup 仅在初始加载时设置动画

javascript - HTML 表单的某些部分未通过 POST 发送

javascript - 将颜色从数组设置为多个元素

java - "this"关键字的类型?

Java:什么被认为更具可读性, "this"或没有 "this"

java - 我可以向单个属性添加多个字段吗

iphone - 我可以对 iPhone Enterprise 应用程序使用私有(private) API 吗?