ES6特性整理和疑惑总结

一、ES6是什么

      官方上说是2015年6月正式发布javascript的语言的下一代标准。我的理解是,相当于使用语法的更新。而语言分为两方面来看的话,就是数据的容器和数据的操作。数据的容器由小到大是数据类型,数据对象,然后不断衍生的符合一些特定场景的新特性的容器,和生活中的水盆和茶壶类似;数据的操作则是为了更好的将容器中的数据进行存取。这是一门语言所能赋予的绝大部分的编写特性了。就是在更合适的环境,用更合适的方法,做实现数据结果的操作。

      下面是自己整理的结构脑图。参考阮一蜂的es6博客http://caibaojian.com/es6/proxy.html。以及深入理解ES6这本书。

二、学习前和学习过程中产生的疑惑和问题

 详细内容在书和博客中介绍的很详细,现在要做的是梳理结构。思考难点和未把握好的点。然后单点突破,从而加深对相关知识的掌握程度。

(1)Es6是什么?是一门新技术吗?对比Es5,核心是否有什么变化?还有ES7,Es8吗?

(2)新增的数据类型let和const什么情况下用更合适?如何理解函数的作用域和变量提升?新增数据类型symbol的作用是什么?

(3)新增的map容器和set容器适合在怎样的数据场景下使用。对应的容器的增删改查的方式?map、set和Array之间如何转换?WeakSet的实际作用是什么,什么情况下会用到这个?

(4)弱引用和强引用的差别和对应的场景差异,对应的缺点和优点。常见的强用和弱引用的方式有哪些?

(5)js单线程的特性下,如何通过异步处理多个事件。Es6的异步处理机制对比ES5有哪些差别和改进的地方。Generator、Promise以及ES5中对应的处理异步的方式分别是什么?据有逻辑上的先后顺序的异步程序块如何实现其中的逻辑关联顺序?异步实现出现错误后的处理错误的机制是什么?Generator函数和async函数的联系和差别

(6)在需要处理大量异步事件的模块中,广泛运用的场景里,比如webpack中,是通过哪种方式处理的异步?

(7)扩展运算符是多数组的遍历和取值,是否可以对对象使用?

(8)assign、apply,call函数的作用、关联和差别是什么?

(9)如何自定义一个类似set,map的数据容器,对于数据的存储和删除有着其独特的数据容器?

  三、带着结构和问题去寻找答案

3.1 es6不是新技术,重要的事情说三遍。看完了大致描述之后,发现es6中的众多新特性只是在es5原有的基础上增加了新的语法糖。比如class类,是在原有的原型链基础上,constructor构造方法等同于prototype.constructor,还是使用的原型链上面的构造方法。而在class中定义的function也是在原型链上面定义的方法。

3.2 let对应的是块级作用域,不存在变量提升的问题。const在申明的时候必须赋值.关于作用域的描述:在es5中,对于作用域的描述是:函数作用域和全局作用域。所有的申明都会上升到作用域的顶端,而函数申明高于变量申明。在相同作用域的情况下每个变量只会申明一遍,其它的申明都会被忽略。 相比之下let不存在变量提升,因此变量在块级作用域内不会影响其它块级作用域的声明和使用.

使用场景分析:除去全局变量外,尽量使用let.const申明一个对象时,无法更改对象的引用,但是可以更改对象的属性。这样可以避免在使用过程中的赋值错误。从内存开销的角度看,全局作用域的开销也是比块级作用域要大的。

3.3  set容器主要使用场景是去重。同时可以通过filter和has配合使用实现数据块之间的交集、并集、差集

/*Set实现交集*/
var m=[1,2,3,2,2,3,4,5];
var filterm=[4,5]
var b=new Set(m);//实现数组去重
var changec=Array.from(b);
console.log(changec);
var mSet=new Set(m);
var bSet=new Set(filterm);
var filterChange=[...mSet].filter(v=>bSet.has(v));
console.log(filterChange);//[4,5]
/*Set实现差集*/
var filterChangeSecond=[...mSet].filter(v=>!bset.has(v));
console.log(filterChangeSecond);//[1,2,3]
/*Set实现并集*/
var addAll=[...filterChange,...filterChange2];
console.log(addAll);[4,5,1,2,3]
/*
Set中的增删改查 add()增加返回set结构本身;delete()删除返回bool;has()查询返回bool;clear()无返回值;
*/
/*map对应的增删改查的方式*/
var testmap=new Map();
testmap.set("ceshi",1);
testmap.has("ceshi");
testmap.delete("ceshi");
testmap.clear();
testmap.keys();
testmap.entries();//返回对应的mapIterator结构的数据格式
/*map和数组之间的相互转换*/
var arrayToMap=new Map(["test",1],["showIt",3]);//转换成对应键值对的map类型数据

Map容器主要的场景是,键值为对象的情况。常见的对象也可以看作键值对,但是键的值只能是字符串,而不能是对象。

3.4 弱引用和强引用常见在对象的赋值和更改值的过程中。弱引用的赋值是对应着相同的内存值,更改后影响到了原数据值

/*对应的弱引用赋值*/
var testChange=[1,2,3,4];
var alsoTestChange=testChange;
alsoTestChange.push(8);
console.log(testChange);//[1,2,3,4,8]
console.log(alsoTestChange);//[1,2,3,4,8];
/*对应的强引用赋值,concat*/
var testchange1=[1,2,34];
var getChange=testchange1.concat([1,2]);
console.log(testchange1);//[1,2,34]
console.log(getChange);//[1,2,34,1,2]
/*更加常用的强引用赋值方式*/
var testchange2=[1,2,34];
var getChange=JSON.parse(JSON.stringify(testchange2));getChange.push(3);
console.log(testchange1);//[1,2,34]
console.log(getChange);//[1,2,34,3]

   3.5 javascript是基于单线程事件循环概念构件的,这是官方的表述。对比java和c++语言。单线程亦为着只允许一个代码块在执行,而多线程就是多个代码块同步执行。对于基于线程的软件而言。多个代码块同时访问并改变状态,程序很难维护并保证状态不会出错。而单线程就不存在这个问题。但是单线程同样需要处理未来才会发生的事件。也就是异步事件处理方案了。  下面是针对处理多个任务整理的思维脑图。

3.6. webpack中处理模块的异步导入方式,是通过创建异步队列。判断对应的异步事件状态,最后Promise.all()方法执行。下图参考自博客。

3.7  ...扩展运算符,类似于执行数组的遍历。可以执行对对象的赋值。

var objectClone=[1,2,3,4,4];
var CloneNext=[...objectClone];
var testObject={name:"xiaoming",age:12};
var cloneObject={...testObject};
console.log(CloneNext);
console.log(cloneObject);

3.8 assign是用于合并两个数据对象的。apply和call方法,我理解为调用函数的另一种方式,差别为传参方式的不同,call传参是单个的值。而apply传参是一个数组。apply可以用于实现比较帅的函数柯里化。

function curry (fn, currArgs) {
    return function() {
        let args = [].slice.call(arguments);

        // 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接
        if (currArgs !== undefined) {
            args = args.concat(currArgs);
        }

        // 递归调用
        if (args.length < fn.length) {
            return curry(fn, args);
        }

        // 递归出口
        return fn.apply(null, args);
    }
}
function sum(a, b, c) {
    console.log(a + b + c);
}

const fn = curry(sum);

fn(1, 2, 3); // 6
fn(1, 2)(3); // 6
fn(1)(2, 3); // 6
fn(1)(2)(3); // 6

3.9  通过Proxy的方式设置对象代理,等同于在语言层面上修改,相当于面向语言编程

/*实现一个当对象中不存在属性名时,默认返回值为 37的自定义容器*/
const handler = {
    get: function(obj, prop) {
        return prop in obj ? obj[prop] : 37;
    }
};

const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b);      // 1, undefined
console.log('c' in p, p.c); // false, 37

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值