两者之间有什么区别

var A = function () {
    this.x = function () {
        //do something
    };
};

and

var A = function () { };
A.prototype.x = function () {
    //do something
};

当前回答

原型是类的模板;这适用于它的所有未来实例。而这是对象的特定实例。

其他回答

在大多数情况下,它们本质上是相同的,但第二个版本节省了内存,因为只有一个函数实例,而不是每个对象都有一个单独的函数。

使用第一个表单的原因是访问“私人成员”。例如:

var A = function () {
    var private_var = ...;

    this.x = function () {
        return private_var;
    };

    this.setX = function (new_x) {
        private_var = new_x;
    };
};

由于javascript的作用域规则,private_var可用于分配给this.x的函数,但不能在对象外部使用。

每个对象都链接到原型对象。当试图访问不存在的属性时,JavaScript将在对象的原型对象中查找该属性,如果该属性存在,则返回该属性。

函数构造函数的prototype属性引用使用new时使用该函数创建的所有实例的原型对象。


在第一个示例中,您将向使用a函数创建的每个实例添加属性x。

var A = function () {
    this.x = function () {
        //do something
    };
};

var a = new A();    // constructor function gets executed
                    // newly created object gets an 'x' property
                    // which is a function
a.x();              // and can be called like this

在第二个示例中,您将向原型对象添加一个属性,所有使用a创建的实例都指向该属性。

var A = function () { };
A.prototype.x = function () {
    //do something
};

var a = new A();    // constructor function gets executed
                    // which does nothing in this example

a.x();              // you are trying to access the 'x' property of an instance of 'A'
                    // which does not exist
                    // so JavaScript looks for that property in the prototype object
                    // that was defined using the 'prototype' property of the constructor

总之,在第一个示例中,函数的副本被分配给每个实例。在第二个示例中,所有实例共享函数的单个副本。

当您使用原型时,函数只会被加载到内存中一次(取决于您创建的对象数量),并且您可以随时重写该函数。

正如其他人在第一个版本中所说的那样,使用“this”会导致类A的每个实例都有自己的函数方法“x”的独立副本。而使用“prototype”将意味着类A的每个实例将使用方法“x”的相同副本。

这里有一些代码显示了这种细微的差异:

// x is a method assigned to the object using "this"
var A = function () {
    this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
    this.x = function() { alert( value ); }
};

var a1 = new A();
var a2 = new A();
a1.x();  // Displays 'A'
a2.x();  // Also displays 'A'
a1.updateX('Z');
a1.x();  // Displays 'Z'
a2.x();  // Still displays 'A'

// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };

B.prototype.updateX = function( value ) {
    B.prototype.x = function() { alert( value ); }
}

var b1 = new B();
var b2 = new B();
b1.x();  // Displays 'B'
b2.x();  // Also displays 'B'
b1.updateX('Y');
b1.x();  // Displays 'Y'
b2.x();  // Also displays 'Y' because by using prototype we have changed it for all instances

正如其他人所提到的,选择一种或另一种方法有多种原因。我的样本只是为了清楚地展示差异。

第一个示例仅更改该对象的接口。第二个示例更改该类的所有对象的接口。