两者之间有什么区别

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

and

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

当前回答

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

其他回答

正如其他答案中所讨论的,这确实是一个性能考虑因素,因为原型中的函数与所有实例化共享,而不是为每个实例化创建的函数。

我制作了一个jsperf来展示这一点。实例化类所需的时间有着巨大的差异,尽管只有在创建许多实例时,它才真正相关。

http://jsperf.com/functions-in-constructor-vs-prototype

每个对象都链接到原型对象。当试图访问不存在的属性时,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

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

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

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

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的函数,但不能在对象外部使用。

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

我相信马修·克鲁姆利是对的。它们在功能上(如果不是结构上)是等效的。如果使用Firebug查看使用new创建的对象,可以看到它们是相同的。然而,我的偏好是以下。我猜这似乎更像我在C#/Java中所习惯的。也就是说,定义类、定义字段、构造函数和方法。

var A = function() {};
A.prototype = {
    _instance_var: 0,

    initialize: function(v) { this._instance_var = v; },

    x: function() {  alert(this._instance_var); }
};

EDIT并不意味着变量的范围是私有的,我只是想说明如何用javascript定义类。变量名称已更改以反映这一点。