可能的重复: 使用“原型”vs。JavaScript中的“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;
}

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


当前回答

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

当你这样做的时候:

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称这样创建的方法为“特权”,因为它们既可以访问公共数据,也可以访问私有数据。

其他回答

在第一个例子中,每个单独的动物都有自己的set_name函数属性,而在第二个例子中,它们通过原型共享相同的函数。

第一个版本的优点是方法可以访问构造函数内部声明的局部(私有)变量。

第二种方法的优点是它需要更少的内存(因为你只存储方法一次而不是一百万次),并且在当前的JS引擎中性能更好。

使用第二种方法,您还可以修改或向类中添加方法,同时影响已经创建的实例。

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

当你这样做的时候:

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称这样创建的方法为“特权”,因为它们既可以访问公共数据,也可以访问私有数据。

当您从这些函数创建新对象时,就会出现差异

var animal1 = new animal();

由第一个函数创建的所有对象将具有不同的name和set_name属性。但是,由第二个函数创建的所有对象将共享set_name属性。