[译]JavaScript需要类吗?
[译]JavaScript需要类吗?
原文:http://www.nczonline.net/blog/2012/10/16/does-javascript-need-classes/
译者注:在我长达一年的工作生涯中,我遇到过有人把构造函数称做类,还有人把对象字面量称做类.这比把火狐扩展叫成插件都令我*疼.下面是Brendan Eich给今年的jsconf.eu录制的视频,其中提到了类.
无论你喜欢还是不喜欢,ECMAScript 6中将会包含类(class)这个新东西了[1].在JavaScript中,对类的需求一直都有两极分化的趋势.有些人特别喜欢JavaScript中没有类,因为这和其他语言不同.另一方面,还有一些人厌恶JavaScript没有类,因为这和其他语言不同.那些从C++或Java转到JavaScript的人们最需要克服的一个心理障碍就是"JavaScript中没有类",有些人和我说过,这就是他们为什么不喜欢Javascript或者不继续深入学习Javascript的原因之一.
JavaScript从发明的那天起就没有真正的类,这使得从一开始就造成了混乱.有不少JavaScript书籍或文章中都讲到了类,就好像JavaScript中真的存在类一样.但其实,他们所说的类只是一些自定义的构造函数,这些函数可以用来构造一些自定义的引用类型.在JavaScript中,引用类型已经是最接近于类的东西了.下面的代码你应该已经很熟悉了:
function MyCustomType(value) {
this.property = value;
}
MyCustomType.prototype.method = function() {
return this.property;
};
很多时候,这种代码被解释为是声明了一个MyCustomType类.但实际上,该代码做的所有事情仅仅是声明了一个MyCustomType函数,配合new运算符可以用它创建一个引用类型MyCustomType的实例.该函数和其他的函数并没有什么本质的不同.因为其他自定义的函数也可以作为构造函数来使用.
这样的代码从表面上看起来根本不像是在定义一个类,被定义的构造函数和其原型对象上的方法似乎没有什么联系.如果是JavaScript新手,很可能会认为这是两段完全无关的代码.但实际上,这两段代码有非常紧密的联系,只是和其他语言中的类的写法相差甚远罢了.
更令人困惑的是,一旦谈到继承,大部分人想到的术语是子类和超类等等,这样的概念只有在存在真正的类的前提下才有意义.在JavaScript中,实现继承的代码同样是冗长的:
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = new Animal(null);
Dog.prototype.bark = function() {
console.log("Woof!");
};
实现继承需要两个步骤,创建构造函数和重写原型对象,这样的代码非常混乱.
在第一版的《JavaScript高级程序设计》中,我使用过术语"类".但从我收到的反馈中看,这样写是很令人困惑的.所以在第二版中,我把所有的"类(class)"都替换成了"类型(type)".事实表明,使用"类型"这个术语可以减少很多的混乱.
可是,还有一个比较突出的问题:定义一个自定义类型的语法是冗长的,实现两个类型之间的继承会更加复杂.没有什么简单的方法可以调用一个属于超类型的方法.在目前看来,创建并管理一个自定义类型是件很痛苦的事,如果你不信,可以看看有下面有多少JavaScript框架使用了自己的定义自定义类型和继承的方法:
- YUI – 用
Y.extend()来实现继承.使用该方法会在子类型上添加一个"superclass"属性.[2] - Prototype – 用
Class.create()和Object.extend()来处理对象和"类".[3] - Dojo – 使用
dojo.declare()和dojo.extend().[4] - MooTools – 有一个自定义类型
Class,可以用来定义和扩展"类".[5]
这么多的JavaScript框架都有自己的解决方案,这明显是非常混乱的.JavaScript开发者们需要一种更好的实现此功能的语法.
ECMAScript 6中的类其实并没有什么新东西,只是在你已经熟悉的模式上增加了一层语法糖.看看下面这个例子:
class MyCustomType {
constructor(value) {
this.property = value;
}
method() {
return this.property;
}
}
这个ECMAScript 6中的类定义其实就是本文上面那个MyCustomType例子的另一种写法.使用这种类创建的对象实例完全和使用构造函数创建的对象实例一样.唯一的区别就是前者拥有更紧凑的语法.下面看看继承的写法:
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
bark() {
console.log("Woof!");
}
}
在实际效果上这个例子也同样等同于前面那种继承的写法.只是复杂的实现步骤被一个简单的extends关键字代替了.在类定义中你还可以直接使用super(),无需明确指出超类型的构造函数.
ECMAScript 6中的类是基于你已经熟知的JavaScript模式.实现继承的原理还和以前一样(基于原型链,调用超类型的构造函数),方法添加在原型上,属性在构造函数中声明.真正的区别只有一个:你可以打更少的字.
所以,如果你现在仍然不赞同ECMAScript 6引入类这么个东西,你可以这么想,要引入的这个类不是什么新东西,也并没有从根本上改变JavaScript的工作机制.不过我个人更推荐使用关键字type而不是class.
那么JavaScript真的需要类吗?答案是不需要,但JavaScript的确需要一个更简洁的方法来创建自定义类型.这恰巧就是ECMAScript 6中的"类"正要做的.如果这个"类"能帮助来自其他语言的开发者们更容易的转向JavaScript,那么它就是好东西.
参考
- Maximally minimal classes (ECMA)
- YUI extend() (YUILibrary)
- Prototype Classes and Inheritance (Prototype)
- Creating and Enhancing Dojo Classes (SitePen)
- MooTools Class (MooTools)
[译]JavaScript需要类吗?的更多相关文章
- 详解javascript的类
前言 生活有度,人生添寿. 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客 Javascript从当初的一个"弹窗语言",一步步发展成为现在前后端 ...
- Javascript定义类(class)的三种方法
将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...
- Atitit.javascript 实现类的方式原理大总结
Atitit.javascript 实现类的方式原理大总结 1. 实现类的式::构造方法方式:原型方式:构造方法+原型的混合方式 1 2. 原型方式(function mode)经典式..实现属性推荐 ...
- [转]Javascript定义类的三种方法
作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...
- javascript 定义类(转载)
Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用来支持虚函数的virtual,不过,Javascript是一门 ...
- javascript定义类和类的实现
首先说说类,在一个类里我们会有以下的几个特征: 1. 公有方法 2. 私有方法 3. 属性 4. 私有变量 5. 析构函数 我们直接看一个例子: /***定义类***/ var Class = fun ...
- javascript创建类的6种方式
javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...
- JavaScript一个类继承中实现
JavaScript类是默认原型对象继承: var Person = function() { this.name = "people"; this.hello = functio ...
- Javascript创建类和对象
现总结一下Javascript创建类和对象的几种方法: 1.原始的创建方法: <script type="text/javascript"> var person = ...
随机推荐
- html中a标签的target属性
_blank -- 在新窗口中打开链接 _parent -- 在父窗体中打开链接 _self -- 在当前窗体打开链接,此为默认值 _top -- 在当前窗体打开链接,并替换当前的整个窗体(框架页) ...
- SqlServer SqlBulkCopy批量插入 -- 多张表同时插入(事务)
这段时间在解决一个多个表需要同时插入大量数据的问题,于是在网上找了下,查到说用SqlBulkCopy效率很高,实验后确实很快,10万条数据只要4秒钟,用ef要用40秒.但是我的还需两张表同时插入,且需 ...
- 17.Delete Methods-官方文档摘录
介绍delete的方法 MongoDB provides the following methods to delete documents of a collection: db.collectio ...
- linux下安装mysql(mariadb)
yum安装软件(官网很慢) yum install mariadb 发现版本如下,版本特别低,且安装包特别小, mariadb x86_64 :-.el7_5 base 8.9 M .我们可以配置ma ...
- PNPoly算法代码例子,判断一个点是否在多边形里面
写C语言的实验用到的一个算法,判断一个点是否在多边形的内部.C的代码如下: int pnpoly(int nvert, float *vertx, float *verty, float testx, ...
- 六、Mosquitto 高级应用之SSL/TLS
mosquitto提供SSL支持加密的网络连接和身份验证.本章节讲述次功能的实现. 在此之前需要一些准备工作. 准本工作: 一台 Linux 服务器. 安装好 openssl (不会明白怎么安装 op ...
- mysql5.7 linux安装参考
安装参考: https://www.cnblogs.com/ianduin/p/7679239.html http://blog.csdn.net/wb96a1007/article/details/ ...
- The 15th UESTC Programming Contest Preliminary D - Destr0y City cdoj1558
地址:http://acm.uestc.edu.cn/#/problem/show/1558 题目: D - Destr0y City Time Limit: 3000/1000MS (Java/Ot ...
- 解决Ubuntu sudo apt-get install遇到的E: Sub-process /usr/bin/dpkg returned an error code (1)问题
如题,本人在安装samba等软件的时候,在命令行敲入: sudo apt-get install samba4命令的时候,系统在下载之后报错,大致内容如下: ~$ sudo apt-get insta ...
- Java-线程池专题(什么是线程池,如何使用,为什么要用)
1.什么是线程池: java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池 多线程技术主要解决处理 ...