美文网首页
自己对es6的查漏补缺

自己对es6的查漏补缺

作者: AAA前端 | 来源:发表于2019-03-15 10:41 被阅读0次
  1. const声明变量不能改变,如果声明的是一个引用类型,则不能改变它的内存地址(比如应用一个对象,可以改变对象里面的值,但是不能重新把变量赋值)
const obj = {name:'zs', age:14}
obj.name = 'ls';// ok
obj = {name:'ls', age:14};// fail

  • 对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错
let foo;
let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"

let baz;
let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz"

let foo;
({foo} = {foo: 1}); // 成功

let baz;
({bar: baz} = {bar: 1}); // 成功

  1. let/const的特点,ES6规定它们不属于顶层全局变量的属性(let/const定义的变量不再绑定到window对象上了)
const name = 'zs';
var age = 14;
console.log(window.name);//undefined
console.log(window.age);// 14
  • let/const声明的变量x是在一个叫script作用域下的,而var声明的变量因为变量提升所以提升到了全局变量window对象中,这使我们能放心的使用新语法,不用担心污染全局的window对象

  1. 箭头函数对于使用function关键字创建的函数有以下区别
  • 箭头函数没有arguments(建议使用更好的语法,剩余运算符替代)

  • 箭头函数没有prototype属性,没有constructor,即不能用作与构造函数(不能用new关键字调用)

  • 箭头函数没有自己this,它的this是词法的,引用的是上下文的this,即在你写这行代码的时候就箭头函数的this就已经和外层执行上下文的this绑定了(这里个人认为并不代表完全是静态的,因为外层的上下文仍是动态的可以使用call,apply,bind修改,这里只是说明了箭头函数的this始终等于它上层上下文中的this)


  1. iterator迭代器
  • 它却是另外4个ES6常用特性的实现基础(解构赋值,剩余/扩展运算符,生成器,for of循环)

  • 对于可迭代的数据解构,ES6在内部部署了一个[Symbol.iterator]属性,它是一个函数,执行后会返回iterator对象(也叫迭代器对象,也叫iterator接口),拥有[Symbol.iterator]属性的对象即被视为可迭代的


    image.png
  • 默认具有iterator接口的数据结构有以下几个,注意普通对象默认是没有iterator接口的(可以自己创建iterator接口让普通对象也可以迭代)

    • Array

    • Map

    • Set

    • String

    • TypedArray(类数组)

    • 函数的 arguments 对象

    • NodeList 对象(是一个类似数组的对象,它的成员是节点对象。Node.childNodes、document.querySelectorAll()返回的都是NodeList实例对象.)

iterator迭代器是一个对象,它具有一个next方法所以可以这么调用

image.png
  • next方法返回又会返回一个对象,有value和done两个属性,value即每次迭代之后返回的值,而done表示是否还需要再次循环,可以看到当value为undefined时,done为true表示循环终止

  1. 解构赋值
let {a:name}= {a:'zs'};
console.log(name); // zs

数组解构的原理其实是消耗数组的迭代器,把生成对象的value属性的值赋值给对应的变量


  1. 剩余/扩展运算符
  • 剩余/扩展运算符同样也是ES6一个非常重要的语法,使用3个点(...),后面跟着一个数组,它使得可以"展开"这个数组

  • 扩展运算符
    只要含有iterator接口的数据结构都可以使用扩展运算符
    扩展运算符可以和数组的解构赋值一起使用,但是必须放在最后一个

    image.png
  • 剩余运算符
    剩余运算符最重要的一个特点就是替代了以前的arguments

function fn1(a,b,c){
  console.log(arguments[0], arguments[1], arguments[2])
}
fn1(1,2,3);

function fn2(...rest){
  console.log(rest) 
}
fn2(1,2,3,['5','6'],{name:'zs'}) ;// [1,2,3,[['5','6']],{name:'zs'}]

剩余运算符和扩展运算符的区别就是,剩余运算符会收集这些集合,放到右边的数组中,扩展运算符是将右边的数组拆分成元素的集合,它们是相反的


在对象中使用扩展运算符
这个是ES9的语法,ES9中支持在对象中使用扩展运算符,之前说过数组的扩展运算符原理是消耗所有迭代器,但对象中并没有迭代器,我个人认为可能是实现原理不同,但是仍可以理解为将键值对从对象中拆开,它可以放到另外一个普通对象中

let obj = {a:1, b:2};
let obj2 = {...obj, c:3}; // {a:1, b:2, c:3}
  • 另外一个ES6新增的API相似,即Object.assign,它们都可以合并对象,但是还是有一些不同Object.assign会触发目标对象的setter函数,而对象扩展运算符不会

  • 使用扩展运算符可以快速的将类数组转为一个真正的数组


    image.png
  • 合并多数组


    image.png

  1. for ... of循环
  • for ... of是作为ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构并且返回各项的值,和ES3中的for ... in的区别如下(这就是不能用for of遍历普通对象的原因,对象没有Symbol.iterator属性)

    1. for ... of遍历获取的是对象的键值,for ... in 获取的是对象的键名

    2. for ... in会遍历对象的整个原型链,性能非常差不推荐使用,而for ... of只遍历当前对象不会遍历原型链

    3. 对于数组的遍历,for ... in会返回数组中所有可枚举的属性(包括原型链),for ... of只返回数组的下标对于的属性值

函数默认值配合解构赋值

image.png
  • 第一行给func函数传入了2个空对象,所以函数的第一第二个参数都不会使用函数默认值,然后函数的第一个参数会尝试解构对象,提取变量x,因为第一个参数传入了一个空对象,所以解构不出变量x,但是这里又在内层设置了一个默认值,所以x的值为10,而第二个参数同样传了一个空对象,不会使用函数默认值,然后会尝试解构出变量y,发现空对象中也没有变量y,但是y没有设置默认值所以解构后y的值为undefined

  • 第二行第一个参数显式的传入了一个undefined,所以会使用函数默认值为一个空对象,随后和第一行一样尝试解构x发现x为undefined,但是设置了默认值所以x的值为10,而y和上文一样为undefined

  • 第三行2个参数都会undefined,第一个参数和上文一样,第二个参数会调用函数默认值,赋值为{y:10},然后尝试解构出变量y,即y为10

  • 第四行和第三行相同,一个是显式传入undefined,一个是隐式不传参数

  • 第五行直接使用传入的参数,不会使用函数默认值,并且能够顺利的解构出变量x,y

  1. Proxy
  • Proxy作为一个"拦截器",可以在目标对象前架设一个拦截器,他人访问对象,必须先经过这层拦截器,Proxy同样是一个构造函数,使用new关键字生成一个拦截对象的实例,ES6提供了非常多对象拦截的操作,几乎覆盖了所有可能修改目标对象的情况(Proxy一般和Reflect配套使用,前者拦截对象,后者返回拦截的结果,Proxy上有的的拦截方法Reflect都有)


    image.png
    image.png

实际应用:
handler.apply
apply可以让我们拦截一个函数(JS中函数也是对象,Proxy也可以拦截函数)的执行,我们可以把它用在函数节流中

image.png

调用拦截后的函数


image.png

vue

  • 尤大预计2019年下半年发布Vue3.0,其中一个核心的功能就是使用Proxy替代Object.defineProperty
  • Vue内部使用Object.defineProperty进行的数据劫持,而这个API无法探测到对象根属性的添加和删除,以及直接给数组下标进行赋值,所以不会通知渲染watcher进行视图更新,而理论上这个API也无法探测到数组的一系列方法(push,splice,pop),但是Vue框架修改了数组的原型,使得在调用这些方法修改数据后会执行视图更新的操作
  • Proxy就没有这个问题,并且还提供了更多的拦截方法,完全可以替代Object.defineProperty,唯一不足的也就是浏览器的支持程度了
    image.png
    掘金翻译的尤大Vue3.0计划

参考资料 :
https://juejin.im/post/5bb719b9f265da0ab915dbdd
https://juejin.im/post/5c6234f16fb9a049a81fcca5

  1. ES6 module
    (requier,module.exports是commonjs的 exports其实指向的是module.exports.)
    ( import export es6的)
  • export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
  • 上面代码输出变量foo,值为bar,500毫秒之后变成baz。

这一点与CommonJS规范完全不同。CommonJS模块输出的是值的缓存,不存在动态更新

  • ES6模块加载的实质
  • ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。

相关文章

  • 自己对es6的查漏补缺

    const声明变量不能改变,如果声明的是一个引用类型,则不能改变它的内存地址(比如应用一个对象,可以改变对象里面的...

  • 【Android面试查漏补缺】之事件分发机制详解

    前言 查漏补缺,查漏补缺,你不知道哪里漏了,怎么补缺呢?本文属于【Android面试查漏补缺】系列文章第一篇,持续...

  • 查漏补缺

    如果想让HTML5标签兼容低版本浏览器的话,可以使用 html5shiv js来实现。注意:一定要把它引入到前面。...

  • 查漏补缺

    图文环绕和浮动 最初的CSS只是用来写文章,熟练使用float和clear两个属性来布局: float属性:指定一...

  • 查漏补缺

    1.js字符串转换成数字与数字转换成字符串的实现方法https://www.2cto.com/kf/201612/...

  • 查漏补缺

    浮动原理 1.使用之初:是为了让文字环绕图片,并且不会遮住文字。如果让图片与文字有间距,我们在浮动元素上添加。2....

  • 查漏补缺

    今天数学老师外出学习,我用了一上午的时间给孩子们查漏补缺。 首先,训练朗读:从段落与段落之间的大停顿...

  • 查漏补缺

    1 Python提供了ord()和chr()函数,可以把字母和对应的数字相互转换2 写 u'中' 和 u'\u4e...

  • 查漏补缺

    generator(生成器) 什么是生成器:把一个列表推倒式l = [x for x in range(10)]改...

  • 查漏补缺

    session 判断

网友评论

      本文标题:自己对es6的查漏补缺

      本文链接:https://www.haomeiwen.com/subject/hyikmqtx.html