本文真没啥难点,我就是为了检验我英语水平退化了没哈哈虽然我英语本来就渣翻译起来也像大白话。将原文看了一遍也码完翻译了一遍差不多一个小时,其中批注部分是自己的理解如有疏漏或误解还请指出感激不尽呐,比如JavaScript中对于单例的理解感觉定义有些模糊啊。
翻译自斯托扬·斯蒂凡诺夫的原文链接:http://www.phpied.com/3-ways-to-define-a-javascript-class/
引言
当涉及到语法时JavaScript是一个非常灵活的面向对象语言。这篇文章你可以找到三种方式定义和实例化一个对象。即使你已经用了某个你喜欢的方式,下面的介绍帮助你去了解一些别的方式有助于你阅读别人的代码。
需要注意的是在JavaScript中没有类的概念,但是通过 Function 可以模拟类,JavaScript中基本一切事物皆对象,在继承方面,对象继承对象而不是类继承类。
1.使用 function
这可能是最通用的一种方法了,定义一个JavaScript function然后通过 new 关键字创建一个实例对象,通过这个function, this 关键字来给这个实例对象添加属性和方法。下面是一个例子。
function Apple (type) { this.type = type; this.color = "red"; this.getInfo = getAppleInfo; } // anti-pattern!(反模式) keep reading... function getAppleInfo() { return this.color + ' ' + this.type + ' apple'; }
这个对象实例的创建需要用Apple构造器函数,添加一些属性然后调用一些方法,请继续看:
var apple = new Apple('macintosh'); apple.color = "reddish"; alert(apple.getInfo());
1.1.方法定义在内部
在上面例子中我们看到Apple"类"的getInfo方法分隔出来被定义为 function getAppleInfo() 。这样看起来工作的很好,但有一个弊端——你可能会在最后定义许多类型这样的functions,它们都在"全局命名空间"。这意味着当你用相同的名字创建另一个function(或者使用了其他的库)会产生命名冲突。为了防止这种现象,你可以将方法定义在构造器函数内部,就像这样:
function Apple (type){ this.type = type; this.color = "red"; this.getInfo = function() { return this.color + ' ' + this.type + ' apple'; } }
这种语法创建实例和之前的并没什么区别。
1.2.方法被添加在原型属性上
1.1的方式中仍然存在弊端,在每一次创建新实例的时候 getInfo() 方法会被每次都添加到实例对象上。有时这可能不是你想要的,一个有效的方法添加 getInfo() 就是将其定义在构造函数的原型属性上。
function Apple (type) { this.type = type; this.color = "red"; } Apple.prototype.getInfo = function() { return this.color + ' ' + this.type + ' apple'; };
可以与1.和1.1相同的方式使用。
2.使用对象自面量
在JavaScript中对象字面量是一个快速精简的方式去定义一个对象实例或数组实例,为了创建一个空对象你可以:
var o = {};
来代替通用的方法:
var o = new Object();
创建数组实例你可以:
var a = [];
来代替:
var a = new Array();
这样的方式你可以跳过类从而立即创建实例(object)。下面仍用先前的例子描述,这次用对象字面量的语法:
var apple = { type: "macintosh", color: "red", getInfo: function () { return this.color + ' ' + this.type + ' apple'; } }
这种方式你不必通过类创建一个实例,因为这个实例对象已经存在了,你只需要使用它就好:
apple.color = "reddish";
alert(apple.getInfo());
这种实例有时被叫做单例,在一些典型的语言比如Java,单例意味着对于某个类任何时候你只能有一个单一的实例,你不能从相同的类中创建更多实例对象。但在JavaScript中这个概念是没有意义的因为所有的对象都是从单例开始的(批注:JavaScript中最大的原生对象就是Object,它既是对象也是构造函数,它只有一个,其他原生对象Function,Array等也是,所以JavaScript实现的是单例继承了单例?? ,任何时候都可以创建一个自面量对象)。
3.在函数中使用单例
第三种方式是前两种方式的结合,你可以使用函数来定义一个单例对象,这是语法:
var apple = new function() { this.type = "macintosh"; this.color = "red"; this.getInfo = function () { return this.color + ' ' + this.type + ' apple'; } }
这定义和1.1非常相似,在使用实例对象上和2相似。
apple.color = "reddish";
alert(apple.getInfo());
new function(){...} 做了两件事:定义了一个函数(匿名构造器)并使用 new 调用它。这可能看起来有点迷惑如果你之前没怎么用过的话,但是这是一个很好的选择,当你真的需要一个构造函数而又只使用一次并且又不用给它赋名时。(批注:这种方式好像看起来好简洁,因为给单例指定了类型,记得《高程》里给单例指定类型叫“增强的模块模式”,对于此例的话用法如下:
var apple = function (){ var obj = new Apple(); return obj; }();
)
总结
通过上面三种方式创建实例对象,JavaScript是没有类的定义的,真是个神奇的语言...