ECMAScript6:主要是甜

TASTY

ES6给JS世界带来的变化是巨大的,与以往“小打小闹”对比起来,这次的语法糖是真的甜。这次我就结合平时的工作情况,把一些我认为真正解决了开发者痛点的语法糖一一挪列出来。有什么不足,请评论处指正。

Features

for-of 数组遍历

var a = ["a","b","c","d","e"];
for(var idx in a){
  console.log( idx );
}
// 0 1 2 3 4 索引值
for(var val of a){
  console.log( val );
}
// "a" "b" "c" "d" "e" 内容

for (var c of "hello") {
  console.log( c );
}
// "h" "e" "l" "l" "o"

for({x:o.a} of [{x:1},{x:2},{x:3}]){
  console.log( o.a );
}
// 1 2 3
  • 这是最简洁、最直接的遍历数组元素的语法
  • 这个方法避开了for-in循环的所有缺陷
  • 与forEach()不同的是,它可以正确响应break、continue和return语句

Arrow Function 函数表达式

先从JavaScript箭头符号说起。

“趋向于“运算符是什么?<!-- 又是什么?

看个例子就明白了。

<!-- 我是被完美的注释掉了
var a = 2;
while(a --> 0){
  console.log(a);
}
//0,1

实际上JavaScript从语言诞生之日起就已经把箭头符号利用上了,下表做了一个大致的统计

符号 作用
>> 位运算
<!-- 单行注释
--> "趋向于"运算符
<= 小于等于
=> 这是什么鬼?

先来看看=>在代码中大概长什么样?

var f2 = x=>x*2;
var f3 = (x,y) => {
    var z = x*2+y;
    y ++;
    x *= 3;
    return (x+y+z)/2;
};

这样的写法是不是比以前传统函数写法简洁得多?简单来说,(var1,var2...) => {Function Body} 这样的函数表达式,我们通常称之为Lambda表达式

All the capabilities of normal function parameters are available to arrow functions, including default values, destructuring, rest parameters, etc.(所有普通函数参数所包含的能力,包括默认值设置、重构、冗余等等都适用于箭头函数)

然而不仅仅如此

再来看一段代码

var controller = {
  makeRequest: function(..) {
      var self = this;
      btn.addEventListener( "click", function(){
        // ..
        self.makeRequest(..);
        }, false );
      }
};

这是传统的做法,在btn点击事件回调方法中用的this和外面的this不一样,为了保留上下文中的this变量,将this赋值给了self。相信这种问题在开发的过程中大多数人都已遇到无数次了。来看看Lambda函数表达式怎么做?

var controller = {
  makeRequest: function(..) {
      btn.addEventListener( "click", () => {
        // ..
        this.makeRequest(..); }, false );
      }
};

自从有了Lambda,我的代码少了几百行!!

Lambda虽好,可不能滥用

来看一段代码

var controller ={
  makeFunction:function(){
     console.log(this);
     this.helper();
  },
  makeLambda : () => {
     console.log(this);
     this.helper();
  },
  helper : () => {
    console.log('ok!!!')
  }
};

controller.makeFunction();//[object Object]  ok!!!
controller.makeLambda();//reference fails

引用《You Don't Know JS ES6》书中解释是

because this here doesn’t point to controller as it normally would. Where does it point? It lexically inherits this from the surrounding scope. In this previous snippet, that’s the global scope, where this points to the global object. Ugh.(这个this并没有如我们预想的那样指向controller,那么指向哪了呢?语义上从环境范围中继承了this对象。在之前的代码片段中,就是全局范围,也就是全局对象)

我补充一句,在浏览器环境下就是Window对象。另外再看一个栗子。

var controller ={
  makeFunction:function(a,b){
    console.log("Function arguments object:" +arguments[0]);
  },
  makeLambda : (a,b) => {
    console.log("Lambda arguments object:" +arguments[0]);
  },
  foo : function(i){
    // foo's implicit arguments binding
    var f = (i) => arguments[0]+i;
    return f(2);
  }
};
controller.makeFunction(1,2);//Function arguments object:1
controller.makeLambda(1,2);//Lambda arguments object:undefined
console.log(controller.foo(1));//3

貌似都在说明,不管是this还是arguments对象都只能在闭包环境下才能正常使用。除此之外,如果想用lambda函数当做“Object Method”,首先还得确定该函数是否对自己有所引用亦或者用到了arguments参数,否则请谨慎使用;

Block-Scoped Declarations & let&const 块级作用域

JavaScript和Java的关系,正如雷锋与雷峰塔的关系一样。

说这些,无非就是想跟Java套套近乎。一直以来,JS中无块级作用域一直为人所诟病。不仅仅是Java程序员,包括C系所有语言等开发者都不能理解。举个栗子。

(function doSth(){
    var a=1;
    for(var i=0;i<2;i++){
       var a=2;
       console.log(a);//2
      }
    console.log(a);//2
})();

for语句块内声明的变量覆盖了外层变量。ES6为了兼容,并没有完全颠覆之前的var声明,而是推出了新的声明标识符let,把for循环中var改成let就可以了

(function doSth(){
    var a=1;
    for(var i=0;i<2;i++){
       let a=2;
       console.log(a);//2
      }
    console.log(a);//2
})();

另外一个const关键字,定义常量,除此之外,它和let的作用几乎是一样的。

Destructuring & default 解构与默认值

解构实际上是一种全新的赋值形式,相比以往更加灵活,代码量更是少少少!!!大概就是这样的。

function foo() {
  return [1,2,3];
}
//传统做法
var tmp = foo(),
a = tmp[0], b = tmp[1], c = tmp[2];
//解构赋值
var[a,b,c] = foo();
var [,,c] = foo();//可以留空
var [a,...c] = foo();//可以通过不定参数指定最尾元素
//对象解构
var { foo, bar } = { foo: "dbs", bar: "asd" };
console.log(foo);// "dbs"
console.log(bar);// "asd
//解构参数
function foo({x,y}){
  console.log( x, y );
}
foo( { y: 1, x: 2 } );// 2 1
foo( { y: 42 } );// undefined 42
foo( {} );// undefined undefined

不得不说,解构(Destructuring)是可以支持任意嵌套(Nested)的!另外就是默认值(Default)了,这又是一个代码精简的利器。

function foo() {
  return [1,2,3];
}
var [a=3,b=6,c=9,d=12] = foo();
console.log( a, b, c, d ); // 1 2 3 12

//参数解构及默认值混合用法
function f6({x=10}={},{y}={y:10}){
  console.log( x, y );
}
f6(); // 10 10

这块就介绍到这,平时多用用就熟了。

Spread & Rest 分散与聚合

根据用法的理解,暂时翻译为分散和聚合。
ES6也为此扩展了一个新的标识符...。我们继续用代码来看看怎么用吧。

function foo(x,y,z) {
  console.log( x, y, z );
}
//invoke function 的时候
foo( ...[1,2,3] ); // 1 2 3
//等价于ES6之前Apply的用法
foo.apply( null, [1,2,3] ); // 1 2 3
//上下文环境可以是数组内
var a = [2,3,4];
var b = [1,...a,5];
console.log( b ); // [1,2,3,4,5]

...用在一个数组(其实对象也可以)前面,它可以表现为将数组中的值遍历到对应的独立的位置上。是为分散。

function foo(x, y, ...z) {
  console.log( x, y, z );
}
foo( 1, 2, 3, 4, 5 ); // 1 2 [3,4,5]

这种用法就是把分散的值合并成为一个数组,是为聚合。

Template Literals 模板字符串

学过C语言第一次写Hello的时候,就已经用到了这个功能,那么今天,ES6终于把这个收入囊中。

function upper(s) {
  return s.toUpperCase();
}
var who = "reader"
var text = `A very ${upper( "warm" )} welcome to all of you ${upper( `${who}s` )}!`;
console.log( text );
// A very WARM welcome to all of you READERS!

能理解上面的,基本就不用我继续解释了。
这篇文章先介绍到这里,ES6的新特性还远远不止这些。下篇会从代码组织的角度来更进一步介绍。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 特别说明,为便于查阅,文章转自https://github.com/getify/You-Dont-Know-JS...
    杀破狼real阅读 559评论 0 0
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 3,351评论 0 1
  • ES6(ECMAScript2015)的出现,无疑给前端开发人员带来了新的惊喜,它包含了一些很棒的新特性,可以更加...
    gtt21阅读 224评论 0 0
  • 你可能已经听说过ECMAScript 6(简称 ES6)了。ES6 是 Javascript 的下一个版本,它有很...
    米塔塔阅读 921评论 0 10
  • 品牌 理念 借势 股权 品牌: 实际竞争对手是 消费者心智模式 定位决定了地位 没有先后 只有认知 没有那个企业强...
    风中筑巢阅读 108评论 0 0