2016-11-3 蓝蓝设计的小编
生活有度,人生添寿。
Javascript从当初的一个“弹窗语言”,一步步发展成为现在前后端通吃的庞然大物。javascript的受欢迎程度也是与日俱增,今年编程语言又是花落javascript,这实在是一个充满了活力的语言。如今,随随便一个网页javascript代码量都不下数千行,要是node后端那更不止几千行了。(WTF)代码量的增加给编程带来的首要的问题就是如何去编写和维护如此庞大的代码呢?答案就是模块化思想,其实就是面向对象(OOP)编程,如今比较流行的三大前端框架(angular,react,vue)基本都实现了组件化编程,但组件化和我们所说的模块化又有所不同,应该可以这么理解,组件化是模块化的升级版,模块化是组件化的基础。那么,问题来了,javascript怎么面向对象编程呢?我想这很多老鸟也不定说的清楚吧,前端杂而活跃的各种社区,很多前端er一度依赖各种插件,根本不需要去了解这些深层的东西却照样能完成任务。但我想作为一个有追求的前端er还是很有必要去学习这些看似用不着的东西的,别的不说,就单单因为我们是前端er,只会用jquery一个稍微厉害的后端都能代替你。好吧,废话不多说,到底如何面向对象coding呢…..
很不幸,es5中并没有给出明确的定义‘类’的概念,所以传统的面向对象编程似乎是行不通的,那么又该肿么办呢?值得庆幸的是,前辈们通过不断探索总结,成功的用javascript模拟出了“类”。那么,javascript的类又该怎么定义呢?
在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称”实例”)共有的属性和方法。
说到javascript中的“类”就不得不说原型链和继承了,因为javascript是没有真正意义上的类的,所谓的类就是基于原型链和继承来实现的,即使ES6中加入了class,extends关键字实现类和继承,但实际上还是基于原型链和继承, ES6 类(class)是 JavaScript 现有的原型继承的语法糖。
“ 在 javaScript 中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null 为止(也就是不再有原型指向),组成这条链的最后一环。这种一级一级的链结构就称为原型链(prototype chain)。 ”
实际上在定义一个对象的时候原型链本身就已经生成了,javascript处处皆对象的思想放在这里理解起来就很容易了,看完后你会发现万物始于Object.prototype。那么我们都是如何定义一个对象的呢,博主总结的方法如下几个:
先初步来个demo具体解释下原型链是咋回事吧:
来来来,撸袖子搞出个对象!!!(马上狗节,单身狗请自觉阅读完此篇博客)
demo如下:
使用构造函数的方法
在 JavaScript 中,构造器其实就是一个普通的函数。当使用 new 操作符 来作用这个函数时,它就可以被称为构造方法(构造函数)。——MDN
demo如下:
使用Object.create创建对象
ECMAScript 5 中引入了一个新方法:Object.create()。可以调用这个方法来创建一个新对象。新对象的原型就是调用 create 方法时传入的第一个参数:
var a = {a: 1};// a ---> Object.prototype ---> nullvar b = Object.create(a);// b ---> a ---> Object.prototype ---> nullconsole.log(b.a); // 1 (继承而来)继承概念下面会讲var c = Object.create(b);// c ---> b ---> a ---> Object.prototype ---> nullvar d = Object.create(null);// d ---> nullconsole.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype
使用 class 关键字
ECMAScript6 引入了一套新的关键字用来实现 class。使用基于类语言的开发人员会对这些结构感到熟悉,但它们是不一样的。 JavaScript 仍然是基于原型的。这些新的关键字包括 class, constructor, static, extends, 和 super.
"use strict";class Polygon {constructor(height, width) {this.height = height;this.width = width;}}//定义一个类Polygonclass Square extends Polygon {constructor(sideLength) {super(sideLength, sideLength);}//使用super引用父类get area() {return this.height * this.width;}set sideLength(newLength) {this.height = newLength;this.width = newLength;}}//使用extends定义Squeare继承父类Polygonvar square = new Square(2);//实例对象//此时的原型链为://square--->Square.prototype--->Polygon.prototype--->Object.prototype--->null//如果不理解为什么是这样,不要紧接着往下看类的说明
继承
其实在上面讲原型链的时候难以避免的也提到了继承,比如来自MDN的这个实例:
—-以上内容来自MDN继承与原型链
我想看到这里还是有些似懂非懂吧,那么来个例子吧:
我想现在应该是明白了吧,再不明白博主也是无能为力了,表达能力实在有限。
总算说到类了,由于javascript的类基于原型链和继承,因此在上面的内容中就已经定义了很多的类。咱们javascript的类同样能实现传统类的多态,封装,继承等特性,这里主要讲解了继承这个概念,但实际上很多时候不经意可能就用了这三个特性。很好玩不是么
首先,我们先看下在ES5中定义一个类的形式:
}
}
好的,然后我们看下在ES6中改写上面的类:
定义一个类的方法实际上也是上面所说的定义一个对象的方法,类本身就是一个对象,只不过这个对象里面的方法和属性可以供许多实例对象调用而已。
总的来说对于类的理解还是需要不断探索的,路漫漫其修远兮,吾将上下而求索。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务