2008-08-09 84 views
16

有几种方法可以把JavaScript类般的行为,最常见的似乎是基于这样的原型:你用什么样式创建“班级”?

function Vector(x, y, x) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    return this; 
} 

Vector.prototype.length = function() { return Math.sqrt(this.x * this.x ...); } 

和基于封闭的方法类似

function Vector(x, y, z) { 
    this.length = function() { return Math.sqrt(x * x + ...); } 
} 

由于各种原因后者速度更快,但我见过(并经常写作)原型版本,并对其他人的做法感到好奇。

+0

我的测试表明,基于闭包的方法比较慢。你必须为每个对象实例化一个单独的闭包。原型方法与所有实例共享方法。 – 2011-01-20 20:08:21

回答

9

为原型分配函数更好(对于公共方法),因为该类的所有实例都将共享该方法的相同副本。如果像第二个示例中那样在构造函数中分配函数,那么每次创建新实例时,构造函数都会创建一个长度函数的新副本,并将其分配给该实例。

但是如果你每个副本都有它自己的拷贝,主要使用的是正在做即有机会获得在构造函数中声明,并通过关闭继承私有变量私有/特权方法后者的技术是有用的机制。

道格拉斯克罗克福德有一个很好的summary

2

那么,我真的没有专家对此的意见。 我通常最终只使用基于闭包的方法,因为它使代码更容易管理。但是,我发现自己正在使用具有多行代码的方法的原型。

2

此外,还可以选择:

function Vector(x, y, z) { 
    function length() { 
    return Math.sqrt(x * x + ...); 
    } 
} 

这可能只是因为例如两个慢,但它看起来更象Java/C#和有点更加明确。

3

幸运的是我可以使用prototype.js,它提供了一些很好的包装。所以,你可以这样做:

var Person = Class.create({ 
    initialize: function(name) { 
     this.name = name; 
    }, 
    say: function(message) { 
     return this.name + ': ' + message; 
    } 
}); 

Prototype.js Documentation: Defining classes and inheritance

+0

我不认为OP是要求隐藏细节的包装。他想知道为什么你会选择任一种方法,所以他可以权衡利益 – 2011-01-20 20:10:48

4

也有对象文学方法的原型:

var Vector = function(){}; 

Vector.prototype = { 
    init:function(x,y,z) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    }, 
    length:function() { 
    return Math.sqrt(x * x + ...); 
    } 
}; 

var v1 = new Vector(); 
v1.init(1,2,3); 
+0

如果你从别的方面继承,那么你不能设置文字原型对象,这将覆盖以前的原型 – 2011-01-20 20:08:51

1

我使用John Resig's library这是一个大风扇。轻量级的,直接的,如果你熟悉'惯常'的面向对象风格,你已经知道如何使用它。

1

JavaScript中没有类。

但是有物体。你不需要一个类来在javascript中创建一个对象。它有constuctor功能,您可以用新的调用,例如:

var james = new Person(); 

您可以模拟类像行为:

原型例如:

function Car (type) { 
    this.type = type; 
    this.color = "red"; 
} 

Car.prototype.getInfo = function() { 
    return this.color + ' ' + this.type + ' car'; 
}; 

对象字面例如

var car = { 
    type: "honda", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' car'; 
    } 
}