本文真没啥难点,我就是为了检验我英语水平退化了没哈哈虽然我英语本来就渣翻译起来也像大白话。将原文看了一遍也码完翻译了一遍差不多一个小时,其中批注部分是自己的理解如有疏漏或误解还请指出感激不尽呐,比如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是没有类的定义的,真是个神奇的语言...

【译】3 ways to define a JavaScript class的更多相关文章

  1. 【译】10个机器学习的JavaScript示例

    原文地址:10 Machine Learning Examples in JavaScript 在过去的每一年,用于机器学习(Machine Learning)的库在变得越来越快和易用.一直以来Pyt ...

  2. 【译】你应该了解的JavaScript数组方法

    让我们来做一个大胆的声明:for循环通常是无用的,而且还导致代码难以理解.当涉及迭代数组.查找元素.或对其排序或者你想到的任何东西,都可能有一个你可以使用的数组方法. 然而,尽管这些方法很有用,但是其 ...

  3. [Python Cookbook] Pandas: 3 Ways to define a DataFrame

    Using Series (Row-Wise) import pandas as pd purchase_1 = pd.Series({'Name': 'Chris', 'Item Purchased ...

  4. correct ways to define variables in python

    http://stackoverflow.com/questions/9056957/correct-way-to-define-class-variables-in-python later say ...

  5. 大型 JavaScript 应用架构中的模式

    原文:Patterns For Large-Scale JavaScript Application Architecture by @Addy Osmani 今天我们要讨论大型 JavaScript ...

  6. [转]大型 JavaScript 应用架构中的模式

    目录 1.我是谁,以及我为什么写这个主题 2.可以用140个字概述这篇文章吗? 3.究竟什么是“大型”JavaScript应用程序? 4.让我们回顾一下当前的架构 5.想得长远一些 6.头脑风暴 7. ...

  7. JavaScript Modules

    One of the first challenges developers new to JavaScript who are building large applications will ha ...

  8. Top JavaScript Frameworks, Libraries & Tools and When to Use Them

    It seems almost every other week there is a new JavaScript library taking the web community by storm ...

  9. 深入了解Javascript模块化编程

    本文译自Ben Cherry的<JavaScript Module Pattern: In-Depth>.虽然个人不太认同js中私有变量存在的必要性,但是本文非常全面地介绍了Javascr ...

随机推荐

  1. 怎样设置table中td的高度为1px

    在制作edm时会遇到须要设置td的高度为1px,假设td标签中有 时不管你怎么设置td的高度都没用,最小高度都是18px. 这时须要把表格中的 去掉.例: 原来是这种: <tr> < ...

  2. swift - 之 UICollectionView的用法/自定义流布局

    具体代码如下: 1.声明 var hCollectionView:UICollectionView? var layout:UICollectionViewFlowLayout? let course ...

  3. os.path模块【python】

    os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...

  4. 说说M451例程讲解之LED

    /**************************************************************************//** * @file main.c * @ve ...

  5. [SQL]躺着也中枪的datetime类型

    写在前面 本来这个东西,我是不想在这里总结的,今天有初学者的朋友问我了,那就不得不说说了,你肯定也踩过这样的坑,没遇到,说明你运气好,编码习惯好.那还是言归正传吧.避免你中枪,还是扫一眼这篇文章吧. ...

  6. SpringMVC配置session过期拦截器,返回登录页面

    spring-mvc.xml配置 <mvc:interceptors> <!-- session失效拦截器 --> <mvc:interceptor> <!- ...

  7. DAG 的最短路径算法

    求图中节点的单源最短路径可以使用Dijkstra,BellmanFord, SPFA算法,而对于有向无环图DAG来说,可以通过简单的动态规划来进行求解.     DAG的独特之处是所有节点可以线性化( ...

  8. poj_3352 连通图的桥

    题目大意 给定N个点,他们之间用一些双向边连通,使得这N个点两两相互可达.但是其中某些双向边为桥,这样若断开这些桥,则整个图就无法做到点之间两两可达.现在可以添加若干条双向边,使得断开图中的任意一条边 ...

  9. c++11——改进容器性能

    使用emplace_back就地构造 emplace_back能就地通过参数构造对象,不需要拷贝或者移动内存,相比push_back能更好的避免内存的拷贝和移动,使得容器插入元素的性能得到进一步提升. ...

  10. MQTT的学习研究(一)MQTT学习网站

    MQTT的官方推荐网站: http://mqtt.org/software 使用IBM 的MQTT协议实现push消息地址: http://tokudu.com/2010/how-to-impleme ...