访问原型父级

时间:2015-09-05 07:41:26

标签: javascript class inheritance prototype this

假设我有一个Posts课程。

我能做到:

Posts.prototype.foo = function () {
  console.log(this);
}

当我调用post1.foo()post1Posts类的实例)时,控制台输出的this将等于post1 }。

现在考虑以下情况:

Posts.prototype.baz = {
  foo: function () {
   console.log(this);
  },
  bar: [1,2,3,4]
}

现在当我post1.baz.foo()时,this的值不再是post1,而是{foo: ..., bar: ...}

我的问题是:在第二种情况下,如何从post1内访问foo

3 个答案:

答案 0 :(得分:2)

你正在遇到一个有趣的问题。您正在做的不是Javascript中的常见模式(将嵌套对象分配给原型),表面看起来应该可以正常工作。

Javascript this以两种方式解决。如果您正在使用new实例化一个函数,this将成为对该实例化对象的引用(如您所知)。

但是,this也可以解析为父对象。也就是说,此代码将记录'bar'

var obj = {
    prop: 'bar',
    log: function() { console.log( this.prop ); }
};
obj.log();

因为this引用了函数所在的对象。这就是您案件中发生的事情。范围正在提前解决。

除此之外:如果该功能没有嵌套在对象中,并且您不使用newthis将成为全局对象(window浏览器)。

执行此操作的正确方法可能在Posts的构造函数中,您可以在其中设置this.whatever并将其绑定到实例。这种方法最常用于"私人"变量,但是当你需要向你的类添加计算数据时,或者在你的情况下,声明特定的范围时,它也很有用。

function Posts() {
    var self = this;

    this.baz = {
        foo: function () {
            console.log(self);
        },
        bar: [1,2,3,4]
    }
}

你也可以这样做:

    ...
    this.baz = {
        foo: function () {
            console.log(this);
        }.bind(this),

您可能需要仔细查看为什么需要类原型上的嵌套对象。你能把它分解成所有平面原型方法吗?它是不是需要在每个类实例上实例化的数据,并且可以在其他地方拉出来?

答案 1 :(得分:1)

每当你有一个“this”关键字时,它受到限制的对象取决于调用站点。只在通话网站上。这是一个更深入的讨论you don't know js。我强烈建议你阅读。但是,如果你让我简化它,请考虑这种方式:

每当执行一个函数时,就好像你在执行以下操作一样:

//implicit binding
obj.fn() ~ fn.call(ojb) 
// in this case you are implicitly binding this as the obj

然而,您可以使用

调用该函数
call

或者,如果您想要明确,请使用apply//explicit bining fn.call(obj) //this is explicitly binding obj as this.

post1.baz.foo()

这些的优先级是明确的>隐含的>默认值。

在您的情况下,您正在运行.baz:您的呼叫网站为this。对于规则2,您将baz绑定到post1.baz.foo.call(post1);。您想要的是明确并致电new

谦卑的意见如下

这真是太丑了,所以我感到痛苦。它之所以如此复杂,是因为你正在使用来对抗语言。这可能是因为您尝试以java方式继承。

最后,还有一个绑定,但要避免它:{{1}}。如果可以,永远不要使用新的。 JS不是java,而new的行为非常混乱。如果要实例化新对象,请使用Object.create。

答案 2 :(得分:0)

如果您可以更改此方法的调用方式,则可以访问this内的baz。例如:

post1.baz.foo.call(post1);

将在this Posts类的函数实例中生成fooconsole.log更正对象。

Demo.