从构造函数中附加方法到原型

时间:2010-03-11 22:10:54

标签: javascript prototypal-inheritance

这是在JavaScript中描述“类”或构造函数的教科书标准方法,直接来自 JavaScript的权威指南

function Rectangle(w,h) {
    this.width = w;
    this.height = h;
}
Rectangle.prototype.area = function() { 
    return this.width * this.height;
};

我不喜欢这里悬空的原型操作,所以我试图想办法在构造函数中封装area的函数定义。我想出了这个,我做了期望工作:

function Rectangle(w,h) {
    this.width = w;
    this.height = h;
    this.constructor.prototype.area = function() { 
        return this.width * this.height;
    };
}

我没想到这会起作用,因为this函数中的area引用应该指向area函数本身,所以我无法访问{{来自width的1}}和height。但事实证明我做到了!

this

进一步的测试证实,var rect = new Rectangle(2,3); var area = rect.area(); // great scott! it is 6 函数中的this引用实际上是对正在构建的对象的引用,而不是区域函数本身。

area

结果显示警告,function Rectangle(w,h) { this.width = w; this.height = h; var me = this; this.constructor.prototype.whatever = function() { if (this === me) { alert ('this is not what you think');} }; } 正好是正在构建的对象。那么这里发生了什么?为什么this不是我预期的this

5 个答案:

答案 0 :(得分:5)

我认为正确的答案是你不应该这样做,因为肯尼贝克在评论中说:

  

如果你有一百个矩形,那么你   将重新宣布原型   方法一百次。

答案 1 :(得分:1)

我认为'this'总是指的是调用该函数的对象。

答案 2 :(得分:1)

this的含义取决于函数的调用方式:

  • this通常是指在运行时调用函数的对象,例如当被称为ob.foo()时,foo中的this将引用ob。
  • 如果以无对象提供的方式调用函数,例如只有foo()this指的是全局变量(包含js程序中所有其他全局变量的顶级对象)。
  • .call().apply()中,this引用的对象已提供。

现在,如果你想要一种方法指向你的函数创建函数的对象(即创建时的第二级this),那么你必须重命名更深层this让它透过当前可见的光芒。如果这显然是泥,这应该有助于澄清一点:

function outside() {
    // Here, 'this' refers to the object outside() is called with.
    // Let's "rename" this, to make it visible to inside functions.
    var that = this,
        private = 42;

    return {
        inside: function {
            // here, 'this' refers to the object inside() is called with,
            //  it is hiding outside's this.
            // Also, 'that' refers to the object outside() was called with,
            //  *at the time* outside was called and inside was created.
            // Notice that you can see 'private'
            // (but nobody outside of 'outside()) can!
            return private;
        }
    }
}

上述模式对于使用可以访问私有成员的公共方法创建对象非常有用。有关更好的解释,请参阅Crockford

答案 3 :(得分:0)

这个'指向的内容'是在代码运行时确定的。

这是一个简单的方法来弄清楚'这个'应该是什么。

如果使用'。'引用一个函数,'this'将引用'。'

左侧的任何内容

(这不包括.call和.apply)

var myFn = function () {
return this.name + ' called me';
};

var me = {
name : 'oatkiller',
shoutOut : myFn
};

var you = {
name : 'Matthew',
shoutOut : myFn
};

// im on the left of the dot, so this points to me
me.shoutOut(); // 'oatkiller called me'

// youre on the left of the dot, so this points to you
you.shoutOut(); // 'Matthew called me'

答案 4 :(得分:0)

我认为你真的很接近最后的例子。如何使用特权方法:

function Rectangle(w,h) {
  this.width = w;
  this.height = h;
  var that = this;
  this.area = function() { 
    return that.width * that.height;
  }
}

var rect = new Rectangle(2,3);
console.log(rect.area());

有关详细信息,请参阅Crockford's "Private Members in JavaScript"