10

这是在 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函数本身,所以我无法访问widthheightthis. 但事实证明我愿意!

var rect = new Rectangle(2,3);
var area = rect.area(); // great scott! it is 6

一些进一步的测试证实,函数this内部的引用area实际上是对正在构建的对象的引用,而不是 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不是this我期望的那样?

4

5 回答 5

5

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

如果您有一百个矩形,您将重新声明该原型方法一百次。

于 2010-03-24T16:25:20.593 回答
1

我认为“this”总是指调用函数的对象。

于 2010-03-11T22:20:29.200 回答
1

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

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

现在,如果您想要一种方法来指向创建您的函数的函数的对象(即创建时的第 2 层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以获得更好的解释。

于 2010-03-12T22:05:38.403 回答
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 的“JavaScript 中的私有成员”

于 2010-03-17T14:29:34.307 回答
0

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

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

如果您使用“。” 要引用一个函数,“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'
于 2010-03-12T21:30:39.683 回答