0

今天看到了两种不同类型的 Javascript 函数声明,我想对这两者有更深入的了解:

function Car( model, year, miles ){
   this.model = model;
   this.year    = year;
   this.miles  = miles;
}

/*
 Note here that we are using Object.prototype.newMethod rather than 
 Object.prototype so as to avoid redefining the prototype object
*/
Car.prototype.toString = function(){
    return this.model + " has done " + this.miles + " miles";
};

var civic = new Car( "Honda Civic", 2009, 20000);
var mondeo = new Car( "Ford Mondeo", 2010, 5000);

console.log(civic.toString());

和类型 2:

function Car( model, year, miles ){
   this.model = model;
   this.year    = year;
   this.miles  = miles;
   this.toString = function(){
       return this.model + " has done " + this.miles + " miles";
   };
}


var civic = new Car( "Honda Civic", 2009, 20000);
var mondeo = new Car( "Ford Mondeo", 2010, 5000);

console.log(civic.toString());

特别是“原型”和“this.toString”。

任何人都可以传授一些 JS 智慧的珍珠吗?

4

2 回答 2

6

这里的主要区别在于,在方法 2 中,您将使用您创建的每个新 Car 实例重新定义该方法,这在技术上性能较低。

然而,方法 2 为您提供的一件好事是您可以创建真正私有的实例变量,如下所示:

function Person( _age ){
    var age = _age;
    this.canDrink = function(){
        return age >= 21;
    }
}

var p = new Person(25);
p.canDrink() // true
p.age // undefined, because age is not exposed directly

方法 1 的另一个优点(除了性能之外)是您现在可以更改 on object 的所有实例的功能。例如:

function Person( _age ){
    this.age = _age;
}
Person.prototype.canDrink = function(){
    return this.age >= 21;
}

var a = new Person(15),
    b = new Person(25);
a.canDrink() // false
b.canDrink() // true

Person.prototype.canDrink = function(){ return true }
a.canDrink() // true
b.canDrink() // true

这对于方法 2 是不可能的(不为每个实例更改它)。然而,年龄现在暴露了:

a.age // 15
b.age // 25
于 2012-04-21T23:06:01.297 回答
0

this.toString必须在构造函数中定义,并且只能在 Car 类中找到,而不是从它继承的任何东西(除非特别包含在子类中)。

Car.prototype.toString可以在构造函数之外定义,并且可以在从 Car 类继承的任何类的原型中找到。

于 2012-04-21T22:56:02.517 回答