20

reader我写了from的简短继承代码Person

<script>

/* Class Person. */
function Person(name) {
    this.name = name;
}

Person.prototype.getName = function() {
    return this.name;
}

var reader = new Person('John Smith');
alert(reader.getName());

</script>

或者,我可以删除行 Person.prototype.getName = function() { return this.name; }并在 Person 对象中创建它。例如

<script>
/* Class Person. */
function Person(name) {
    this.name = name;
    this.getName = function() { return this.name;}
}

var reader = new Person('John Smith');
alert(reader.getName());

</script>

getName()在这两种情况下调用时我得到了相同的结果。那么它们有什么不同呢?

4

6 回答 6

24

当您在原型上放置一些东西时,对象的每个实例都共享相同的方法代码。它们都使用相同的函数实例。

当您简单地将方法放在 上时this,每个对象实例都有自己的相同方法的副本

使用prototype效率更高。请注意,这就是为什么通常将方法放置在原型上的原因,因为您通常希望所有实例使用相同的方法,但属性放置在实例本身上,因为通常您不希望所有实例共享相同的属性。

对于您的评论,如果您在对象的构造函数上放置一个方法,那么您实际上创建了一个“静态”方法。对象的任何实例都不会具有该方法,它们都必须在构造函数上访问它。所以在你的情况下,Person.someMethod().

于 2012-07-18T12:34:05.213 回答
4

当您将方法放入构造函数并从该构造函数中创建一个对象时,每个对象都有自己的getName功能。对于 10 个Person实例,每个实例都有自己的getName10 个单独的getName函数。

如果您放置getName在构造函数的原型中,则相同的getName函数将在所有实例之间共享/继承。所以对于 10 个实例Person,每个实例都具有getName但仅引用 1 个getName函数。

使用原型可以节省内存,因为该方法在实例之间共享,因此只使用一个。

于 2012-07-18T12:35:32.900 回答
3

不同之处在于,当您将其放在原型上时,所有实例Person共享相同的代码getName- 您可以通过分配其他内容getName来更改所有实例:Person

Person.prototype.getName = function() { return 'Mr Jones' };

此外,由于它们共享相同的代码,因此占用的内存更少:您只有一个getName函数副本,而不是每个实例一个副本。

另一个区别是您可以稍后将 设置Person为另一个类的原型,比如说Man,它将继承属性/方法。

更新:这是一篇很好的文章,解释了原型的其他属性:https ://stackoverflow.com/a/1534286/295262

于 2012-07-18T12:35:48.027 回答
2

不同之处在于您进一步扩展了 Person 类,子类将不会继承 getName() 方法

编辑:我在上面的陈述中是不正确的。刚刚在jsfiddle上测试过。无论我们是在原型上还是在函数实例本身上定义方法,它都可用于链中的子类。

这是证明:http: //jsfiddle.net/u8qrd/

我知道将方法附加到原型有性能/内存优势。Appart 在继承方面没有任何行为差异吗?

(希望我在这里提问没有违反 SO 规则)

于 2012-07-18T12:35:21.527 回答
0

prototype用基于类的话来说,通过和声明函数之间的区别this是这样的:

原型:

实例的功能如下所示:

somefunc = function(){super()/*call the function of the super-class*/};

这个:

实例的功能如下所示:

somefunc = function(){/* Do same stuff as in the prototype func declared */};

现在更改原型上的函数将不会影响实例。

于 2012-07-18T12:45:19.470 回答
0

当您将任何函数添加this.functionname到任何对象构造函数时,该构造函数创建的每个对象都会制作自己的该函数的副本,该副本也占用内存。想象一下,如果您有多个由同一个构造函数创建的对象,以及它将占用多少内存。另一方面,当您使用cunstructorName.prototype.functionName函数在内存中加载一次并且每个对象共享相同的原型函数构造函数时创建它。这种方法使您的代码在加载和操作时更快,并且还节省了大量内存。

于 2018-09-12T09:51:28.723 回答