JavaScript访问父范围

时间:2017-03-09 16:09:48

标签: javascript scope parent javascript-objects

我很难弄清楚如何访问父级的范围。我的代码如下

var Class = function(){
    this.smth = 3;
}

Class.prototype.setters = {};
Class.prototype.setters.smth = function(smth){
    this.smth = smth;
}

但是,这当然不起作用,会影响smthClass.setters。我尝试使用.bind(Class.prototype);无济于事。 有没有人有办法解决吗?我有很多子方法。

2 个答案:

答案 0 :(得分:2)

当您致电someInstance.setters.smth(...)时,函数调用的thissettings对象,并且smth函数无法知道如何正在访问settings对象,只是它被提供为this

您可以通过在构造函数中为每个实例创建唯一的setters对象来保持所需的语法,但会花费大量内存:

var Class = function(){
    var thisClassInstance = this;
    this.smth = 3;
    this.setters = {};
    this.setters.smth = function(smth){
        thisClassInstance.smth = smth;
    }
}

这不是最理想的,因为你失去了原型继承的好处;每个实例在setters对象中都有一套独特的函数,没有任何共享。

更精简的方法是让每个实例都有自己的setters对象,该对象知道其父实例的身份,但setters对象从原型setter对象继承其所有方法:

// all `setters` object inherit their methods from this object
var settersPrototype = {};

// methods on the `setters` set values on `this.parent`
settersPrototype.smth = function(smth){
    this.parent.smth = smth;
}

var Class = function(){
    this.smth = 3;

    // this instance has a `setters` object that inherits all its methods
    this.setters = Object.create(settersPrototype);
    this.setters.parent = this;
}

这样,每个实例的内存成本都是一个唯一的{ parent: ... }对象,但每个setter函数都有一个原型版本,存在于唯一的settersPrototype对象上。

答案 1 :(得分:1)

你可以通过几种方式做到这一点。你的原型方法还有其他方法,但这可能会让它更清晰:

ES5

var TestClassEs5 = function(){
    // With ES5, store the outer this to variable to preserve
    var self = this;
    this.smth = 3;

    this.setters = {
      smth: function (smth) {
        self.smth = smth;
      }
    }

    return this;
}

ES6

const TestClassEs6 = function(){
    this.smth = 3;

    // Using a fat arrow syntax binds the function to the lexical scope
    this.setters = {
      smth: (smth) => this.smth = smth
    }

    return this;
}

JS Bin: http://jsbin.com/qugatacive/edit?js,console