对构造函数中当前对象的引用

Reference to current object in constructor

本文关键字:对象 引用 构造函数      更新时间:2023-09-26

我试图定义一个类,该类在其构造函数中实例化其他对象,并将引用传递给它们自己:

var Child = function(m) {
  var mother = m;
  return {
    mother: mother
  }
}
var Mother = function() {
  var children = makeChildren();
  return {
    children: children
  }
  function makeChildren() {
    var children = [];
    for (var i = 0; i < 10; i++) {
      var c = new Child(this);      // <--- 'this' is an empty object here
      children.push(c)
    }
    return children;
  }
}

这不起作用,并且Child实例的mother属性中最终有一个空对象。做这件事的正确方法是什么?

Javascript的this不是词法的。这意味着makeChildren得到它自己的this,而不是得到你想要的Motherthis

将一个普通变量设置为该值,然后使用它。

var that = this;
function makeChildren(){
     blabla = that;
}

不过,我认为这样做还不够。通过从构造函数返回一个对象,可以忽略this。设置内容:

this.children = children;

而不是返回一个新对象。

当您从母亲对象内部调用makeChildren((时,您可以尝试传递对母亲对象的引用,可能是这样的:

var Mother = function() {
   var children = makeChildren(this);
}

然后,makeChildren((函数可以接受引用作为参数,您可以使用它:

function makeChildren(ref)
var c = new Child(ref);

不知道这是否有效,但可能值得一试。

嵌套函数不会从其父函数继承this,因此makeChildren()中的this与Mother构造函数中的this不同,除非在调用makeChildren():时显式设置它

var children = makeChildren.call(this);

这应该可以在不对代码进行任何进一步更改的情况下工作。有关.call((.的更多详细信息,请查看MDN

或者,您可以保存对this的引用,并将其传递到函数:

var Mother = function() {
  var self = this; // <-- new variable
  var children = makeChildren();
  return {
    children: children
  }
  function makeChildren() {
    var children = [];
    for (var i = 0; i < 10; i++) {
      var c = new Child(self);      // <--- change 'this' to 'self'
      children.push(c)
    }
    return children;
  }
}

嵌套函数可以访问函数中的局部变量。

var Child = function(m) {
    var mother = m;
    return {
        mother: mother
    }
};
var Mother = function() {
    if (!(this instanceof Mother)) {
        return new Mother();
    }
    var that = this;
    var makeChildren = function() {
        var children = [];
        for (var i = 0; i < 10; i++) {
            var c = new Child(that); // <--- 'that' is the reference to Mother
            children.push(c)
        }
        return children;
   };
   var children = makeChildren();
   return {
       children: children
   }   
};

然后执行:

var m = Mother();

Mother对象中的前三行确保that的值是Mother实例,而不是全局对象。如果没有它们,你将永远不得不写:

var m = new Mother();