JS篇 ES6新特性

注意:

1. Node环境下,--harmony参数启用ES6新特性,这些新特性只有在strict mode下才生效,因此使用"use strict"或者--use_strict,否则harmony没有被启用;

2. Extended Mode: 当启用新特性的时候,context处于extended mode下;而且这些feature仅仅只在strict mode下有效;

 

1. let与const:

  1. 块级作用域(Block scope

  2. let声明

  3. const声明

// Block scope
function f1(){
    console.log("Outside.");
}
(function(){
    if(false){
     // f1定义在if {}之内
function f1() { console.log("Inside."); } } f1(); }());

  ES5中:

  1. strict mode:     将会报错:In strict mode code, functions can only be declared at top level or immediately within another function.(函数只能声明在Glocal scope或者函数里的最外层)

  2. non-strict mode:    输出:"Inside";

  ES6中:

  1. strict mode:     输出:"Outside",(node环境下使用命令:node --harmony --use_strict 1_blockScope.js,使用node 1_blockScope.js --harmony命令,harmony没有起作用)

  2. non-strict mode:  输出:"Inside";(根据上面第一条:non-strict mode下不启用harmony)

  因为ES6中,出现了块级作用域,导致上面的代码在ES6 context的strict mode中是有意义的;

 

  let声明的变量,其作用域仅在块级作用域之内

{
    let a = 1;
    var b = 2;
}
a
b
// ES6下:ReferenceError: a is not defined
// ES5下:SyntaxError: Illegal let declaration outside extended mode

  因为let不会有变量提升,所以输出v1=5, i=10;个人感觉:之前共用函数作用域,现在增加了块级作用域不会增加内存占用吗?

function f1(){
    var list = [];
    for(var i=0; i<10; i++){
        let v1 = i;
        list.push(function(){
           console.log(v1, i);
        });
    }
    list[5]();  // output: 5 10
}
f1();

  IIFE的目的是说:定义的变量存在于函数作用域中,不在最外层Global,避免对Global的污染;基于这一目的,可以使用块级作用域来代替IIFE;

 

  定义常量,node环境下,重新赋值报错:SyntaxError: Assignment to constant variable.

const PI = 3.14;
// SyntaxError: Assignment to constant variable.
//console.log(PI=3.13);
console.log(PI);

     

 

4. Destructing析构赋值

  下面列出了析构的几个常用之处:1. 函数传参;2. 函数返回;3. 函数参数默认值;4. for..of遍历

// 1. Passing arguments
function f1({x, y}){
    console.log(arguments);
}
f1({x:"Hello", y:"Function"});


// 2. Accept function returns
var f1Ret = (function(){
    return {x: "hello", y:"function"};
})();
console.log(f1Ret);


// 3.Passing arguments with fixed arguments
function f1({x="hello", y="world"}){
    console.log(arguments);
}
f1({x:"Hi", y:"Function"});


// 4. for...of
var m1 = new Map();
m1.set("Hello", "World");
m1.set("Hi", "Map");

for(let [k, v] of m1){
    console.log(k, v);
}

5. Number扩展:

  1. Number.isFinite()

  2. Number.isNaN()

  3. Number.isInteger()

"use strict";

/**
 * Number:
 * 1. Number.isFinite(), Number.isNaN()
 * 2. Number.isInteger
 *
 */

console.log("isFinite: ", Number.isFinite(Infinity), Number.isFinite(-Infinity), Number.isFinite(0));

console.log("isNaN: ", Number.isNaN(NaN));

//console.log("parseInt: ", Number.parseInt("13.00"));

console.log(Number.isInteger(3.01));

 

 

 

6. 数组扩展:

1. Array.from(...)   抽取Array-like对象或者Interable对象
2. Array.of(...)     将零散值转换为数组
3. array.fill()      填充
4. find(fn), findIndex(fn)
"use strict";

/**
 * Array:
 * 1. Array.from(...)   抽取Array-like对象或者Interable对象
 * 2. Array.of(...)     将零散值转换为数组
 * 3. array.fill()      填充
 * 4. find(fn), findIndex(fn)
 * 5. Array.observe()   监听
 */

var m1 = new Map();
m1.set("A").set("B");

var a1 = Array.from(m1);
console.log(a1);

console.log(Array.of(10, 20, 30));

console.log([null, null].fill(10));

var a2 = [10, 20];
console.log(a2.find(function (v, i) {
    return v == 10;
}), a2.findIndex(function (v, i) {
    return v == 10;
}));

 

7. 对象扩展:

  1. Object.is

  2. Object.assign

  3. Object.getPrototype

  4. Object.setPrototypeOf

/**
 * Object.is(o1, o2)    判断对象是否相等
 * Object.assign(target, src1, src2)
 * Object.getPrototype(obj)
 * Object.setPrototypeOf(o1, o2)
 * 将对象、方法直接写入对象
 */


console.log("Object.is(+0, -0): ", Object.is(+0, -0), +0 === -0);
console.log("Object.is(NaN, NaN): ", Object.is(NaN, NaN), NaN === NaN);

var o1 = { a1: "1st" };
var o2 = { a1: "2nd" };
var o3 = { a1: "3rd" };
console.log(Object.assign(o1, o2, o3));

console.log(Object.getPrototypeOf(o1) === Object.prototype);
//console.log(Object.setPrototypeOf({}, o1).a1);

var username = "diydyq";
var eat = new Function;
var o4 = {
    username,
    eat,
    o1,
    [username]: username 
};
// { username: 'diydyq', eat: [Function], o1: { a1: '3rd' } }
console.log(o4);

 

 

8. 函数扩展:

  1. 参数默认值

  2. Rest参数(将一系列实参映射到形参数组

  3. 扩展运算符(将数组实参映射到一系列逗号分隔的形参

  4. 箭头函数(this不可更改,arguments指向的不是自身的参数)

"use strict";
var l1 = [10, 20];

/**
 * 参数默认值
 */
var f1 = function (x="default argument") {
    console.log(x);
};
f1();
f1("specified argument");


/**
 * Rest参数:
 * 1. 将一系列实参转换为数组
 */
var f2 = function (name, ...left) {
    console.log(name, left, left instanceof Array);
};
f2("s1", "s2", "s3");

/**
 * 扩展运算符(spread)
 * 1. 将数组实参转换为一系列的形参
 */
var v3 = [10, 20, 30];
var f3 = function (v1) {
    console.log(v1, arguments);
};
f3(...v3);

Math.max.apply(null, v3);
Math.max(...v3);


/**
 * 箭头函数
 * 1. this 绑定了定义时的对象,call|apply却无法更改,为什么不应该呢?
 * 2. arguments变量可以使用,但不是该函数对应的参数,而是包含它的函数的参数
 */
var f1 = v => { console.log(v); };
l1.forEach(f1);

function f2Wrap(){
    var f2 = (v) => { console.log(this == global, arguments, v == arguments[0], v && Object.prototype.valueOf.call(v)); };
    f2();
    f2(l1);
    f2.call(l1, l1);
}

f2Wrap("Test");

 

9. Set与Map操作:

  1. Set:不可重复的数组,可用于数组去重(属性:size;5个方法:set() get() has() delete() clear())

  2. Map: 存放的键名key不限于简单数据类型,支持对象作为键(属性:size;5个方法:set() get() has() delete() clear(),遍历:keys() values() entries())

  3. WeakMap: Traceur中暂不支持(TODO:待使用);

"use strict";
var l1 = [10, 20, 30, 20];
var s1 = new Set(l1);

/**
 * Set对象:
 * 1. 1个属性: size
 * 2. 4个方法:add() delete() has() clear()
 */
console.log(s1, s1.size);
console.log(s1, s1.add(100).delete(10), s1.has(100), s1.size);
console.log(s1.map_);

console.log("-------------------------------------------------");

/**
 * Map对象:
 * 1. 1个属性:size
 * 2. 多个属性:set(), get(), has(), delete(), clear()
 * 3. m.set(k, v) 不同于 m[k] = v; 后者是给这个m对象赋值;
 */
var m1 = new Map();
var o1 = { attr1: "Test" };
var o2 = [10, 20];

m1[o1] = "Value for o1";
m1.set(o1, "Value for o1 new1");
m1.set(o2, "ValueFor o2");

console.log(m1, m1[o1], m1.get(o1), m1.has(o1), m1.delete({}));
console.log(m1);
m1.clear();

m1[0] = "Value for 0";
m1.set(0, "Value, for 0 new1");
console.log(m1[0], m1.get(0), m1, m1.size);


for(let k of m1.keys()){
    console.log(k);
}
for(let v of m1.values()){
    console.log(v);
}
for(let [k, v] of m1.entries()){
    console.log(k, v);
}

/**
 * WeakMap对象:
 * TODO:traceur中找不到
 *
 */
//var wm1 = new WeakMap();
//wm1.set(o1, "Value for o1");
//wm1.set(o2, "Value for o2");
//console.log(wm1.size);

 

11 Generator函数:

  1. 每次yield或者return返回新的对象:{ value: ..., done: false|true }  
  2. return后再次调用next()返回空的value对象: { value: undefined, done: true }
  3. next()传参:
    1) 第一次next传递参数,会报错:ModuleEvaluationError: Sent value to newborn generator
    2) 所以如果第一次需要传参,可以在生成generator时添加;
    3) 后续的next参数,将作为yield表达式的返回值

"use strict";

/**
 * Generator:
 * 1. 每次yield或者return返回新的对象:{ value: ..., done: false|true }
 * 2. return后再次调用next()返回空的value对象: { value: undefined, done: true }
 * 3. next()传参:
 *    1) 第一次next传递参数,会报错:ModuleEvaluationError: Sent value to newborn generator
 *    2) 所以如果第一次需要传参,可以在生成generator时添加;
 *    3) 后续的next参数,将作为yield表达式的返回值
 */
function* generatorFrom1(arg1){
    console.log("Execute generator: ", arg1);
    var o1 = {};
    for(var i=0; i<2; i++){
        o1.idx = i;
        var yRet = yield o1;
        console.log("yield Return: ", yRet);
    }
    return o1;
}

var g1 = new generatorFrom1(), g2 = new generatorFrom1("First time execution.");
var r1, r2;

r1 = g1.next();
r2 = g1.next();
console.log(r1, r2, r1 == r2);
console.log(g1.next(), g1.next());

console.log("----------------------------------");
console.log("Execute 1: start");
r1 = g2.next();
console.log("Execute 1: end");

console.log("Execute 2: start");
r2 = g2.next("argument Test");
console.log("Execute 2: end");
console.log(r1, r2);

 

12 Promise:

  1. Promise的构造函数必须为function,否则TypeError;

  2. catch(fn)用于处理reject的信息;

  3. 如果让下一个执行resolve,则return;否则拒绝的话,使用throw new Error()

  4. Promise.all()参数是一个数组,不是零散的promise对象

"use strict";

/**
 * Promise:
 * 1. Promise的构造函数必须为function,否则TypeError;
 * 2. catch(fn)用于处理reject的信息;
 * 3. 如果让下一个执行resolve,则return;否则拒绝的话,使用throw new Error()
 * 4. Promise.all()参数是一个数组,不是零散的promise对象
 * 5. async功能未成功试用
 */

var fn1 = function(resolve, reject){
    setTimeout(function () {
        console.log("Execute promise function");
        resolve("Resoved Message");
        //reject("Rejected Message");
    }, 1000);
};

//var p1 = new Promise(fn1);
var p1 = new Promise(fn1);

p1.then(function (msg) {
    console.log("1st resolve: ", arguments);
}, function (msg) {
    console.log("1st reject: ", arguments);
    //return "1st pass to 2nd message";
    throw new Error(["1st pass rejected message"]);
}).then(function (msg) {
    console.log("2st resolve: ", arguments);
}, function (msg) {
    console.log("2st reject: ", arguments);
}).catch(function (msg) {
    console.warn("3rd reject: ", arguments);
});


var fn2 = function(resolve, reject){
    setTimeout(function () {
        console.log("Execute promise function");
        resolve("Resoved Message");
        //reject("Rejected Message");
    }, 500);
};
var p2 = new Promise(fn2);


var pAll1 = Promise.all([p1, p2]).then(function (msg) {
    console.log("1st resolve: ", arguments);
}, function (msg) {
    console.log("1st reject: ", arguments);
});

console.log("-----------------------------------");
//async function asyncFn1() {
//    console.log("Async before");
//    let ret1 = await (function () {
//        return new Promise(fn1);
//    })();
//    console.log("Async After");
//}
//asyncFn1();

 

 

 

 

参考:

1. ruanyifeng       http://es6.ruanyifeng.com/#docs/let

2. Stackoverflow    http://stackoverflow.com/questions/17253509/what-is-extended-mode

 

转载于:https://www.cnblogs.com/diydyq/p/4190214.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
曾经听许多前端从业者说:“前端发展太快了。”这里的快,十有八九是说层出不穷的新概念,余下的一二,大抵只是抒发一下心中的苦闷罢——前两日刚习得的新技术转眼就“落后”——仔细品味这苦闷,除却不得不持续奔跑的无奈,更多的是一口气,一口卯足了劲儿也要把新知识全数揽入囊中的不服气。作为刚入行的新人,对这点体会颇深。就像是蓦地从某个时间点切入,半数时间向前走,半数时间向后看,瞻前顾后,回味揣摩这十年间的岁月精魄,还得翘首盼着花花新世界,不时再问自己一句,这样走下去真的会好么?是的,其实答案人尽皆知,同时也无人知晓,因为没人能预言未来,顶多只能预测未来,但有一件事情永不会错,当你笃定地沿着一条路走下去,结果通常不会太糟糕,但凡能在浮躁的社会冷静下来潜心磨砺,多少总会有收获。幸而我有意弱化了对新信息的执念,开始做一些事情,《深入浅出ES6》就是其中一件。 纵观整个系列,亦即纵观ECMAScript 2015的整个体系,吸取了诸多成功经验:借鉴自CoffeeScript的箭头函数;始于C++项目Xanadu,接着被E语言采用,后来分别于Python和JavaScript框架Dojo中以Deferred对象的面貌出现的Promise规范(详见Async JavaScript一书3.1章);借鉴了C++、Java、C#以及Python等语言的for-of循环语句;部分借鉴Mustache、Nunjucks的模板字符串。 当然,新的语言体系也在之前的基础上查漏补缺:弥补块级作用域变量缺失的let和const关键字;弥补面向大型项目缺失的模块方案;标准委员会甚至为JavaScript增加了类特性,有关这一方面的特性褒贬不一,Douglas Crockford曾在2014年的Nordic.js大会发表了题为《The Better Parts》的演讲,重新阐述了他个人对于ECMAScript 6的看法,他认为Class特性是所有新标准中最糟糕的创新(我个人也略赞同这一说法,类的加入虽然有助于其它语言的使用者开始使用JavaScript,但是却无法发挥出JavaScript原型继承的巨大优势);以及为了保持非侵入式弥补其它新特性而诞生的Symbols。 其它的新特性也相当诱人,熟练掌握可以大幅度提升开发效率:迭代器Iterator、生成器Generators、不定参数Rest、默认参数Default、解构Destructuring、生成器Generator、代理Proxy,以及几种新类型:Set、Map、WeakSet、WeakMap、集合Collection。 以上提及的新特性只是其中的一部分,更多的新特性等待着大家进一步挖掘。整个系列的翻译历时150余天,坚持专栏翻译的日子艰苦也快乐,编辑徐川细心地帮我审校每一文章,编辑丁晓昀赠予钱歌川先生详解翻译之著作让我大开眼界,与李松峰老师的交流也让我深刻理解了“阅读、转换、表达”的奥义所在,最感谢我的母亲,在我遇到困难需要力量的时候永远支持着我。选择ES6作为前端生涯的切入点实之我幸,恰遇这样的机会让我可以一心一意地向前走,向未来走。我很敬佩在“洪荒”和“战乱”年代沉淀无数经 验的前辈们,你们在各种不确定的因素中左右互搏,为终端用户提供统一的用户体验,直到如今你们依然孜孜不倦地吸取业内新鲜的经验。技术在进步,也为前端人 提供着无限的可能性,我们有责任也有义务去推动新标准的发展和普及,诚然在商业的大环境下我们不愿放弃每一寸用户的土壤,但携众人之力定将能推动用户终端 的革新。ES7标准的提案纷纷提上日程,用不了多久也将登上前端大舞台。也感谢午川同学友情提供译文《深入浅出ES6(十):集合 Collection》,让我在困难时期得以顺利过渡。最后祝愿国内前端社区向着更光明美好的未来蓬勃生长!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值