首页 > 解决方案 > 构造对象后,如何使 Immediately-Invoked-Func-Expression 能够访问 javascript 中先前定义的属性

问题描述

 var Counter = function(name) {
    this.name = name;
    this.data = (function() {
        console.log(this.name);
    })();
};

var counter = new Counter("some name");

预期行为:打印“某个名称”。

当前行为:没有打印任何内容。

我试图在构造对象后立即使用内部属性“数据”。使用依赖于内部属性“名称”的函数检索此“数据”。但是,当调用立即调用的函数表达式时,它看起来无法访问该this.name属性,因此我无法在对象构造后立即检索我的数据。

我可以通过首先定义一个等价物来使它工作this

var Counter = function(name) {
    var that = {};
    that.name = name;
    that.data = (function() {
        console.log(that.name);
    })();
    return that;
};

var counter = new Counter("some name");

为什么会这样?我怎样才能让它以一种优雅的方式工作?

标签: javascriptiife

解决方案


this在 JavaScript 中因在不同的上下文中发生变化而臭名昭著。内部this函数中的 是全局对象(window如果您在浏览器中运行它),而不是this构造函数中的对象。

根据您所针对的 JavaScript 版本,有几种不同的解决方案:

ECMAScript 5

您可以使用[MDN]传递this值:apply

var Counter = function(name) {
  this.name = name;
  this.data = (function() {
    console.log(this.name);
  }).apply(this);
};

var counter = new Counter("some name");

ECMAScript 6

如果你使用 ES6,你可以使用箭头函数,它会自动绑定this父函数的值:

var Counter = function(name) {
  this.name = name;
  this.data = (() => {
    console.log(this.name);
  })();
};

var counter = new Counter("some name");

ECMAScript 3

与您的问题类似的另一个选项是分配this给一个新变量that。然后你可以that在子函数中引用。

var Counter = function(name) {
  var that = this;
  that.name = name;
  that.data = (function() {
    console.log(that.name);
  })();
};

var counter = new Counter("some name");

apply在 ECMAScript 5 中引入之前,这是最常见的解决方案。


推荐阅读