摧枯拉朽,说说ES6的三把火
我是 Jser 我骄傲
JavaScript 如今可谓是屌丝逆袭高富帅的代名词哈,从当初闹着玩似的诞生到现在 Github 上力压群雄的人气王,JS 搭着互联网的顺风车一路高歌,本身也从一个爷爷不疼奶奶不爱的杀马特小脚本蜕变为一门高大上的主流编程语言。运气固然重要,ES6 也让大家看到了这门语言自身的努力和上进,相信 JavaScript 定大有可为。
ES6 发布于 2015 年 6 月,因此也叫 ES2015,距今已有两年多。2015 年是铭心刻骨的一年,这一年,股市崩盘,千古跌停,手里的两个票更是挨了腰斩,宝宝心里苦。同是这一年,ES6 标准落地,作为一名前端开发,宝宝心里又乐开了花。
ES6 的新语法很多很碎,如果想系统地学习一遍,强烈推荐阮一峰老师的 ECMAScript 6 入门。本文的目的不是要介绍 ES6 的新语法,而是想谈谈 ES6 为JavaScript 这门语言本身带来了什么,同时这也是在咱看来 ES6 最重要最激动人心的特性。
作用域
作用域一直是程序设计语言的基础设施。JavaScript 也有作用域,但它的作用域有点怪,稍不留神就会掉到坑里。
JavaScript 的作用域(scope)有三种类型,分别是 Local,Closure 和 Global,对应的三种变量类型分别是局部变量,闭包变量和全局变量。
比如下面一段代码:
var a = 'global'
function outer(){
var b = 'closure'
return function inner(){
var c = 'local'
console.log(a + ':' + b + ':' + c)
}
}
outer()()
在 Chrome 控制台执行上面代码,当执行 outer()()
时,a
和 outer
都是全局变量,浏览器环境中的全局变量全部挂在全局 window
对象上。b
是闭包变量, 对 outer
函数内定义的函数内部保持可见。c
则是局部变量,只对 inner
函数内部可见。
目前为止看上去似乎没什么问题,接下来看点有问题的:
if(true){
var _a = 1
}
console.log(_a)
正常情况下变量 _a
的值应该是 undefined
才对,然而不要以为你以为就是你以为的。在 JS 中 if
语句块里定义的变量 _a
直接变成了全局变量,也就是通过 window._a
可访问。如果是从C语言,Java等主流编程语言转过来的开发者就会更加迷惑了,这简直就是TMD不科学。
在 JS 中,诸如 for
,while
,switch
等可接大括号的代码块都是不能定义局部变量的,在其中定义的变量通通会是全局变量,也就是说大家已经习以为常的块作用域在 JavaScript 中是不存在的,能够定义局部变量的只有函数这个第一公民。这不科学,不合理,不符合社会主义核心价值观\抓狂。
一声霹雳,ES6 落地,完美地弥补掉了上面 JavaScript 暴露的作用域缺陷。这就意味着从此以后你可以以为你以为的就是你以为的了。ES6 为了向后兼容,var
还是原来的 var
保持不变,在此基础上又新添了一个声明变量的关键字 let
和一个声明常量的关键字 const
。
{
let a = 1
}
console.log(a)
// Uncaught ReferenceError: a is not defined
完善的作用域机制可有效地避免命名污染,提高程序的可靠性,减少隐晦的bug,尤其是在开发大型多人协作项目时作用尤为明显。
鉴于以上所分析的各种利弊,请自始至终地使用 let
,而不要再让 var
这个混小子出现在视线里。用 var
危险,后果自负。
模块系统
模块化,模块化,模块化,重要的事情说三遍,这是工程化的第一要务,是控制软件复杂度的最重要措施,没有之一。然而 2015 年之前的 JavaScript 语言是没有模块系统的。C语言有 include
,Java 有 import
,连 CSS 都有个蹩脚的 @import
,wrnmmp,JavaScript 却只有 undefined
。有条件要上,没条件创造条件也要上。于是乎,JavaScript 社区里的各位勇士造出了各种各样实现模块化的轮子,AMD,CMD,UMD 全蹦出来了。不想用又苦于没有好的解决方案,只能在内心呐喊,这不科学,不合理,不符合···\抓狂。
霹雳哗啦,ES6 落地,带来了原生的模块系统,优雅又简单,丝滑般的体验冲淡了腰斩给咱带来的痛,脸上又洋溢出了久违的笑容。
最基本的使用:
/* add.js */
export function add(a, b){
return a + b
}
上面定义并导出了一个 ES 模块。接下来就可以在任一个逻辑文件里引用:
/* main.js */
import {add} from './add'
add(1, 3)
模块系统哪家强,ES6 最猖狂。ES6 一出,快刀斩乱麻,直接终结了前端长期的模块化乱象,实现了大一统。唯一的遗憾是 Node.js 对 ES6 模块系统的支持还不是无缝过渡。不过这个还好,毕竟 Node.js 的 CommonJS 用起来还是相当顺手的。
有了语言层面的模块系统,JavaScript 也在语言性质上完成了蜕变,不再是一个打遍互联网酱油的小脚本,而成长为一门举重若轻的主流编程语言。
模块系统是大型项目不可或缺的标准配置,对项目的开发和维护都非常重要。所以把它列为 ES6 所带来的最重要特性丝毫不为过。
类(Class)
其实这个特性相比前两个倒是没那么重要,说白了,类(Class)做的就是 JS 原型(prototype)做的那点事——继承,咱觉得这是一个没它也行,有它更好的语法糖功能。之所以把它列在这是因为咱看 prototype 不爽很久了。
JS 基于原型的继承机制借鉴自 Self 语言。正如 JS 的设计者所言“它是 C 语言和 Self 语言一叶情的产物”。原型继承是很不直观的,或者可以说是非主流的。面向对象程序设计中典型的继承是基于类的继承,例如 Java,C++ 等主流编程语言实现的均是基于类的继承。
使用 prototype 会出现 jQuery 的 jQuery.prototype.init.prototype = jQuery.prototype
这种让人瞬间石化的代码。况且咱左看右看,上看下看也没看出来原型继承相较于类式继承有啥优点可言,反而是越看越拙。咱第一眼看到 prototype 这货就很不顺眼,也许是因为从 C++ 开发过来的缘故吧。
好在 ES6 带来了 class
,刚发现这个特性的时候咱乐的一宿没睡着觉,有一种久别重逢,相见恨晚的赶脚。
来看个最简单示例:
/* Shape.js */
export class Shape{
this.x = 0
this.y = 0
}
英雄联盟里的盲僧说过“如果类不是为了继承,那将毫无意义”。
/* main.js */
import {Point} from "./Point"
class Triangle extends Point{
constructor(){
super()
this.sides = 3
}
}
let a = new Triangle()
这代码看着多直观,多大方,多舒坦。面向对象的概念已经在前端被越来越广泛的传播开来,咱是非常推崇 class
的继承方式的,不知道大家喜欢用哪个,反正在咱的代码里已经是看不到 prototype 的影子了。
以上就是咱认为 ES6 带来的三把火。肯定有人要质疑了“怎么没有 Promise 啊”,需要申明一下,Promise 在 node 偏后端开发中比较实用,在前端的日常开发中并不常用,而本文是从偏前端的角度来说的,这是咱这两年开发中受益最大的三个特性。
摧枯拉朽,说说ES6的三把火的更多相关文章
- React与ES6(三)ES6类和方法绑定
React与ES6系列: React与ES6(一)开篇介绍 React和ES6(二)ES6的类和ES7的property initializer React与ES6(三)ES6类和方法绑定 React ...
- 关于阮一峰老师es6(第三版)中管道机制代码的理解浅析
最近正在学习阮一峰老师的es6(第三版)教材,在学到第七章<函数的扩展>中的箭头函数嵌套时,文中提到了一个关于“管道机制”的示例,文中源代码如下: //es6(第三版)教材中的管道机制源代 ...
- 深入浅出ES6(三):生成器 Generators
作者 Jason Orendorff github主页 https://github.com/jorendorff ES6生成器(Generators)简介 什么是生成器? 我们从一个示例开始: ...
- JavaScript学习笔记 -- ES6学习(三) 变量的解构赋值
1.解构赋值的定义 在ES6中,允许按照一定模式,从数组和对象中提取值(所谓解构),然后对变量进行赋值. var a = 1; var b = 2; var c = 3; //等价于 var [a, ...
- ES6核心内容精讲--快速实践ES6(三)
Promise 是什么 Promise是异步编程的一种解决方案.Promise对象表示了异步操作的最终状态(完成或失败)和返回的结果. 其实我们在jQuery的ajax中已经见识了部分Promise的 ...
- 用vue.js学习es6(三):数组、对象和函数的解构
一.数组的解构: 以前的方式: var arr = [1,2,3]; console.log(arr[0]); //1 console.log(arr[1]); //2 现在的方式: var [a,b ...
- es6(三):es6中函数的扩展(参数默认值、rest参数、箭头函数)
1.函数可以设置参数默认值 function test1(x,y=1){ console.log(x,y) } test1(10)//10 1 2.rest参数:形式为...变量名 function ...
- 从零开始学 Web 之 ES6(三)ES6基础语法一
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- ES6基础三(对象)
对象赋值 在es6中,可以直接将声明的变量赋值给对象: Object.keys().Object.values()和Object.entries() 在ES6中,允许我们使用变量作为对象的ke ...
随机推荐
- iOS 从实际出发理解多线程
前言 多线程很多开发者多多少少相信也都有了解,以前有些东西理解的不是很透,慢慢的积累之后,这方面的东西也需要自己好好的总结一下.多线程从我刚接触到iOS的时候就知道这玩意挺重要的,但那时也是能力有限, ...
- Mybatis按顺序获取数据
sql语句select * from producttg where hospitalcode in (1,2,3) 获取到的数据并不是按照条件1,2,3的顺序排列,如果要成下面形式(mybatis ...
- python 小白(无编程基础,无计算机基础)的开发之路 辅助知识1 with...as
这个语法是用来代替传统的try...finally语法的. with EXPRESSION [ as VARIABLE] WITH-BLOCK 基本思想是with所求值的对象必须有一个__enter_ ...
- 移动端效果之LoadMore
写在前面 列表一直是展示数据的一个重要方式,在手机端的列表展示又和PC端展示不同,毕竟手机端主要靠滑.之前手机端之前一直使用的IScroll,但是IScroll本身其实有很多兼容性BUG,想改动一下需 ...
- 【Spring】Spring MVC高级技术
前言 前面学习了简单的Spring Web知识,接着学习更高阶的Web技术. 高级技术 Spring MVC配置的替换方案 自定义DispatcherServlet配置 在第五章我们曾编写过如下代码. ...
- [转]动态管理视图和函数 (Transact-SQL)
动态管理视图和函数返回可用于监视服务器实例的运行状况.诊断故障以及优化性能的服务器状态信息. 重要提示 动态管理视图和函数返回特定于实现的内部状态数据. 在未来的 SQL Server 版本中,它们的 ...
- ionic开发环境搭建之android及问题
1. 准备工作: a) 配置java开发环境 b) 配置安卓开发环境 注:下载android-studio后,可能会出现android一直在编译,出现这种情况,关掉你的as ,找到你的路 ...
- 如何用webgl(three.js)搭建一个3D库房-第一课
今天我们来讨论一下如何使用当前流行的WebGL技术搭建一个库房并且实现实时有效交互 第一步.搭建一个3D库房首先你得知道库房长啥样,我们先来瞅瞅库房长啥样(这是我在网上找的一个库房图片,百度了“库房” ...
- [拓扑排序]Ordering Tasks UVA - 10305
拓扑排序模版题型: John has n tasks to do.Unfortunately, the tasks are not independent and the execution of o ...
- Service 之间如何通信?- 每天5分钟玩转 Docker 容器技术(101)
微服务架构的应用由若干 service 组成.比如有运行 httpd 的 web 前端,有提供缓存的 memcached,有存放数据的 mysql,每一层都是 swarm 的一个 service,每个 ...