原型的目的是什么?

244

可能是重复问题:
JavaScript中使用'prototype'和'this'的区别?

好的,我对JS中OOP的概念还有点陌生。

下面这两段代码有什么区别:

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}
function animal(){
    this.name = 'rover';
}
animal.prototype.set_name = function(name){
    this.name = name;
}

它们都做同样的事情,那么它们有什么区别呢?


1
类的实例级别共享成员(非静态)。例如)Person.prototype.instance_counter = 0; //不能像Person.instance_counter(这是静态的)那样使用ClassName访问。 - Kanagavelu Sugumar
3个回答

341

使用原型可以更快地创建对象,因为每次创建新对象时,原型上的属性/方法不必重新创建。

当你这样做时:

function animal() {
    this.name = 'rover'
    this.set_name = function (name) {
      this.name = name
    }
}

每次创建动物时都会创建 set_name 方法。但是当你这样做时:

animal.prototype.set_name = function (name) {
    this.name = name
}

该方法无需每次重新创建;它存在于原型中的一个位置。因此,当您调用 someAnimal.set_name("Ubu"); 时,this 上下文将被设置为 someAnimal,并且(唯一的)set_name 方法将被调用。


使用第一种语法的一个优点是:以这种方式创建的方法将可以访问私有数据:

function animal() {
    var privateData = 'foo'

    this.name = 'rover'
    this.set_name = function (name) {
        this.name = name
        alert(privateData) //will alert 'foo'
    }
}

Douglas Crockford称像这样创建的方法为“privileged”,因为它们可以访问公共和私有数据。


37

当你从这些函数创建新对象时,差异就会显现出来。

var animal1 = new animal();

第一个函数创建的所有对象都将具有不同的nameset_name属性。然而,第二个函数创建的所有对象将共享set_name属性。


31
在第一个例子中,每个不同的动物都有自己的set_name函数的属性,而在第二个例子中,它们通过其原型共享同一函数。
第一种版本的优点是方法可以访问在构造函数中声明的局部(私有)变量。
第二种方法的优点是它需要更少的内存(因为您只存储方法一次而不是一百万次),并且在当前JS引擎中具有更好的性能。
使用第二种方法,您还可以以影响已经创建的实例的方式修改或添加类的方法。

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