this.method = function(){} 和 obj.prototype.method = function (){} 有什么不同?

3
作为一名C#/.NET开发人员,我喜欢在业余时间玩弄JavaScript——创建自己的库/框架等。诚然,它们并不多(实际上只是一些松散的函数集合),但目的是为了学习,而不是供他人使用。
通常我会通过以下方式扩展基本的JavaScript对象:
obj = function () {
    //basic object stuff
    this.method = function () {
        //other stuff
    };
    return this;
};

这使我能够创建其他对象并链接方法,非常流畅:
obj('arg1').method();

两个例子:jQuery Knock-offList-Item Sorter 然而,最近我看到比我自己写的代码更加函数化的对象以这种方式实现相同的功能:
function obj(){
    //stuff
}
obj.prototype.method = function () {
    //stuff
};

例子:Reddit Chrome扩展

这两种方法似乎都能实现同样的目标,我对这两种语法的外观都没有偏见。有没有特定的情况下其中一种更有用?这些方法提供了什么让它们比另一种更具吸引力的功能?

编辑

考虑以下代码:

var dice = function (sides) {
    this.roll(){
        return 4 //guaranteed to be random
    }
};

var d1 = dice(6);
d1.roll()  // 4;
var d2 = dice(20);
d2.roll()  // 4
d1 和 d2 是不是不同的对象,就像它们对我所显示的那样?或者它们只是指向一个对象(变量 dice)的指针/别名?

1
你的第一个例子有效是因为你实际上是在全局 window 对象上创建了 method,然后返回了全局对象。(除非你省略了一些改变其含义的关键代码)。你的 dice 例子根本不起作用,因为语法无效,并且修复语法后,d1d2 将会是 undefined - user113716
1个回答

13
this.method = function(){};

仅适用于特定实例。

Obj.prototype.method = function(){};

适用于每个Obj实例

但是,为了利用prototype,您应该这样做

var o = new Obj(); // Note that functions intended to be used with "new" should be capitalized

o.method();

骰子示例

我假设您打算在 dice() 函数中使用 return this

这个示例并不常见,因为调用一个函数不会创建一个新的对象。在你的骰子案例中,你将会赋值一个方法给 this,而在函数内部,this 是指全局对象 window ,然后返回它。

这将导致 d1d2 都指向同一个对象(window),并且其中一个方法 roll 会被重新分配。

要实现您想要的效果,您应该使用 new 创建实例,就像这样:

var d1 = new Dice(6); // remember capitalization is important here
var d2 = new Dice(20); 

这样将会创建两个roll函数,是正确的,但浪费了内存,因为可以通过以下方式共享函数:

Dice.prototype.roll = function() { /* return random awesomeness */ };

希望这能澄清事情。


1
如果他给他的第一个函数命名并将其用作构造函数,那么就不会有任何区别,对吧? - Dan
是的,会有这样的情况。方法不会被共享,每创建一个新对象就会有效地创建一个新函数,浪费内存。但行为上不会有任何区别。 - Pablo Fernandez
@Michael,你能编辑你的问题并添加这段额外的代码吗?在这里阅读(和回答)它很困难。 - Pablo Fernandez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接