es6 笔记

es6笔记      



2.let

  1.let声明的变量,存在代码块作用域的限制
  2.for 存在二个作用域()父作用域    {} 子
  3.不存在变量提升,必须先声明后使用          var 会变量提升  严格模式下 未声明变量 就使用会报错,不严格就为全局域的
  4.区块中存在let和const命令,这些命令声明的变量,从一开始就形成了封闭作用域。凡是在 声明之前就使用这些变量,就会报错,在块级作用域里,let和const声明的变量被绑定,必须先声明,声明之前使用就会报错,不管外界是否有该变量(暂时性死区 养成先声明后使用的习惯)

3.块级作用域(只对变量比较严格 ,对函数的处理相当于var声明变量)

        1. let实际上为 JavaScript 新增了块级作用域            ES5 只有全局作用域和函数作用域,没有块级作用域        立即执行函数表达式(IIFE) 可以解决环境污染,闭包的 处理
     2. 浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于var声明的变量(函数名提升)    ES5 中,函数只能在顶层作用域和函数作用域之中声明,所以有函数名提升的感念(浏览器不遵守,所以可以在块级声明)
    3.ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错

 4.const

    const只能保证这个指针是固定的,不可改变指针指引,地址内的值可变,const的作用域与let命令相同:只在声明所在的块级作用域内有效,跟let一样
    对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针(都是内存地址,还有那么大差别)对象冻结,应该使用Object.freeze方法

 5.

    var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。
(语法形式好多都跟python相似,这是要往大方向跑啊)


6.变量解构赋值(遍历)  

    1.let [head, ...tail] = [1, 2, 3, 4]; ...指代[ 留下的全部数值]  映射关系,右侧不存在就为undefine
  可以为默认值  一个数组成员严格等于undefined,默认值是才会生效的  let [foo = true] = [];
     2.let { foo, bar } = { foo: "aaa", bar: "bbb" }; 对象解构  对象的属性没有次序,变量必须与属性同名,才能取到正确的值
        let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者(对象是键值对的形式)
       一个已经声明的变量用于解构赋值 let x; {x}={x:1}   {x}被当做代码块  用({x}={x:1})  对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量let { log, sin, cos } = Math;
      对象解构规则:等号右边的值不是对象或数组,就先将其转为对象
      可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号
      任何部署了 Iterator 接口的对象,都可以用for...of循环遍历   对象解构    可以遍历对象的属性{sin,cos}=math

 7.字符扩展(处理字符大于0xffff的字符)

      码点在\u0000~\uFFFF之间的字符。超出这个范围的字符,必须用两个双字节的形式表示\ud842\udfb7或者\u{41}\u{42}

      codepointat()可以处理二字节以上字符,  codePointAt方法会正确返回 32 位的 UTF-16 字符的码点   codePointAt方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下

      String.fromCodePoint方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode方法的不足 定义在string对象上

      at()返回指定为的字符      chartAt() 

      normalize()用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化
     indexof() 扩展includes():返回布尔值,表示是否找到了参数字符串。startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。 endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。三个方法都支持第二个参数,表示开始搜索的位置
     repeat(n) 重复n次   padstart() padend()  padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串,不满足长度就补全

   8.模板字符

      模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量  引入变量${name}  ,不用像以前去拼接

   9. 函数

        1.函数的默认值是惰性求值 ,可以是表达式求值,只有当参数是undefined时才会赋予默认值

       2.function b({a=1,b=2})   与functionb(a=1,b=2}={ })的区别,第一种是参数是一个对象,但是没有赋予默认值,不要被里面的解构赋值误导;第二种是参数赋予默认值,里面的变量才会寻找值function({a=1,b=2})和function({a,b}={a=1,b=2})区别 注意参数和赋予默认值的区别;注意解构赋值和无解构赋值的区别

   3.参数作用:参数会形成一个单独的作用域(context),参数内部的作用域。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的,意味着,寻找值时先参数内部作用域,后外部,存在很大的不同,像for循环一样也存在二个作用域,由内指向外

      4.参数默认值要放在尾部 ,不然无法省略该参数,函数的属性length,length含义:该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了。同理,后文的 rest 参数也不会计入length属性,如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。

        5.reset  ===[....name]==arguments   rest搭配的变量是一个数组;函数name属性,返回函数名,需要注意的是,ES6 对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5 的name属性,会返回空字符串,而 ES6 的name属性会返回实际的函数名;如果将一个具名函数赋值给一个变量,则 ES5 和 ES6 的name属性都返回这个具名函数原本的名字

       6. ::双冒号改变this指向   obj::fn==fn.call(obj)  

       7.尾调用优化 (调用帧,调用栈)  最后一步操作返回函数做到这一点的方法,就是把所有用到的内部变量改写成函数的参数,即内部函数没有引用外部变量,以参数传入 ,不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,故只保留了一个调用栈。  尾递归是尾调用优化的实现,但在es5下,函数有argumrnts和caller属性会跟踪外层,所以不可尾递归。ES6 中只要使用尾递归,就不会发生栈溢出,相对节省内存

       8.箭头函数this不存在,一般都是指向外层this   function b({a=1,b=2})   与b(a=1,b=2}={})的区别,this被固定 不随对象的改变而改变
  箭头函数有几个使用注意点。
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。es5使用时的环境对象
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
(5)除了this,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:argumentssupernew.target
上面五点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。
  this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数
   

  10  symbol  返回的是一个值

    1.ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)   let s= symbol()  
   2.Symbol 值作为对象属性名时,不能用点运算符,点运算符后面总是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致属性名实际上是一个字符串,而不是一个 Symbol 值。
    3.symbol.for()有则用原来的,无则创,会被记登记,全局    symbol.keyfor()返回被登记的key描述,注意和symbol的区别,一个全局一个非全局

     4.symbol值不能与其他类型的值进行运算,symbol的值可以显示的转换为字符串和布尔值(symbol.tostring()显示),不能转换为数值

      5.可以遍历symbol属性的有getownpropertysymbols和reflect.ownkeys

      6.魔术字符串指的是,某一个具体的字符串或者数值。应该尽量消除魔术字符串,改由含义清晰的变量代替

  11.set map 新的数据结构

     set 去重类似数组   new set([1,1,3,2])   具有add   delete has clear  foreach keys values entries 方法  size属性    array.from和[...set]可将set转为数组   扩展运算符(...)内部使用for...of循环     Map  值值对的数据存储  set get has delete  clear
   set map都会剥去传入数组的外壳    weakset weakmap 都是弱引用 ,机制会不确定的清除

 11.proxy  代理 (注意this指向不确定性,指向proxy实例)对返回的实例操作,不应对代理的对象操作,不会改变代理对象

      修改元数据的默认操作 编程语言进行编程  var proxy = new Proxy(target, handler);   target 处理对象,该对象下的默认方法的修改
      get:function(target,property,proxy实例)  apply方法拦截函数的调用、call和apply操作   has方法用来拦截HasProperty操作,即判断对象是否具有某个属性时,这个方法会生效     construct方法用于拦截new命令,下面是拦截对象的写法   construct方法可以接受两个参数。
target: 目标对象  args:构建函数的参数对象  construct方法返回的必须是一个对象
Proxy.revocable方法返回一个可取消的 Proxy 实例  Proxy.revocable方法返回一个对象,该对象的proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例
      Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即不做任何拦截的情况下,也无法保证与目标对象的行为一致。主要原因就是在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理 故不能访问原对象(透出一个属性访问的的本质,是this的指引访问,所以,对象名改变依然可以访问,把this指针赋予了它,  构造函数返回this对象)

12. refelct  将object对象语言内部的方法映射出来  ,也可以修改  不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为

Reflect.apply(target, thisArg, args)     
Reflect.construct(target, args)
Reflect.get(target, name, receiver)
Reflect.set(target, name, value, receiver)
Reflect.defineProperty(target, name, desc)
Reflect.deleteProperty(target, name)
Reflect.has(target, name)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)
如果 Proxy 对象和 Reflect 对象联合使用,前者拦截赋值操作,后者完成赋值的默认行为,而且传入了receiver,那么Reflect.set会触发Proxy.defineProperty拦截

  13. iterator (处理不同数据结构时的一种同一的规范)

   遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
   Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费 使用for...of循环遍历某种数据结构时,该循环会自动去寻找 Iterator 接口
   遍历器是一种线性处理,对任 何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换
   一个对象如果要具备可被for...of循环调用的 Iterator 接口,就必须在Symbol.iterator的属性上部署遍历器生成方法
Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内

 14.generator 生成器  * 只有调用next方法才执行    任何数据结构只要有 Iterator 接口,就可以被yield*遍历

      Generator 函数是一个状态机,封装了多个内部状态,返回一个可遍历状态的遍历器对象  一步一步执行  卡位,yield表达式就是暂停标志
      Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”) Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行
     yield表达式如果用在另一个表达式之中,必须放在圆括号里面    yield表达式用作函数参数或放在赋值表达式的右边,可以不加括号
     yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上(当前的吧)一个yield表达式的返回值
 

 15.异步编程  

  回调函数
事件监听
发布/订阅
Promise 对象


16.class(只是一种语法糖,本质还是构造函数)(this 很重要,谁有this权(this指向谁)就可以有权调用属性和方法)

   类的数据类型就是函数,类本身就指向构造函数  类的所有方法都定义在类的prototype属性上面
   类的内部所有定义的方法,都是不可枚举的(non-enumerable) es5定义的方法可以枚举
   constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象(导致本身对象失效)
   实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)
   类的原型(构造函数的原型)prototype==实例的原型__proto__  实例没有prototype属性,构造函数才具有
   类的属性名,可以采用表达式[name]='lll'
   类不存在变量提升(hoist),这一点与 ES5 完全不同
   私有方法是常见需求,但 ES6 不提供,只能通过变通方法模拟实现
   属性的存取都是通过get set 用函数封装好的 ,故调用的还是函数
   this 代表定义在实例上的属性或方法    this关键字则代表实例对象,在实例上定义的方法属性,都归属实例 区分定义在实例上的与原型上的  如果静态方法包含this关键字,这个this指的是类,而不是实例。
   constructor方法默认返回实例对象(即this),把this指向谁谁就有权访问
   静态方法只能被类调用 ,可以被子类继承

  new.target 返回new命令作用于的那个构造函数(或者类 内部使用new.target指向当前正在执行的函数)。如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的

 super 指代父类  子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象

  super 关键字  super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。
  super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)。
  super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类 ,定义在实例上的方法和属性无法访问

ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this,默认情况下会存在super()方法

17.arraybuffer   ArrayBuffer对象、TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口

   ArrayBuffer对象代表原始的二进制数据,存放数据的内存,TypedArray 视图用来读写简单类型的二进制数据,如何划分数据形成数组,视图可以直接存入数组,开辟内存,DataView视图用来读写复杂类型的二进制数据    三者都是构造函数
   TypedArray 数组提供 9 种构造函数,用来生成相应类型的数组实例  TypedArray(buffer, byteOffset=0 注意划分字节起始位置, length?)
  x86 体系的计算机都采用小端字节序(little endian),相对重要的字节排在后面的内存地址,相对不重要字节排在前面的内存地址

 18.promise

new Promise(function(reslove,reject){}).then(function(){},function(){})
  Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果 意味着只要状态发生改变,随时都可以获取结果。
  Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署
  resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
  Promise 新建后就会立即执行  resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例  前一个promise的状态影响(它成功就成功)下一个promise
 then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法
 Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获
  Promise.prototype.catch方法是.then(null, rejection)的别名, 处理下一个promise
Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误” ,报错但会继续执行
 一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法,catch方法指定的回调函数,会接着运行后面那个then方法指定的回调函数。如果没有报错,则会跳过catch方法
 将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用

 19.async

     它就是 Generator 函数的语法糖 

20.object

        1. object.is(val,val)判断二个val是否相等,解决了NaN不等于自身的问题,-0不等于+0

         2.object.assgin(target,source) 对象合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),返回目标对象,拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性

         3. Object.getOwnPropertyDescriptor(object,属性)方法可以获取该属性的描述对象,得到数值属性

         目前,有四个操作会忽略enumerablefalse的属性,实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉for...in操作,不然所有内部属性和方法都会被遍历到,ES6 规定,所有 Class 的原型的方法都是不可枚举的。

  • for...in循环:只遍历对象自身的和继承的可枚举的属性。
  • Object.keys():返回对象自身的所有可枚举的属性的键名。
  • JSON.stringify():只串行化对象自身的可枚举的属性。
  • Object.assign(): 忽略enumerablefalse的属性,只拷贝对象自身的可枚举的属性。
     4.ES6 一共有 5 种方法可以遍历对象的属性。

(1)for...in

 for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

(2)Object.keys(obj)

Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

(5)Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

  • 首先遍历所有数值键,按照数值升序排列。
  • 其次遍历所有字符串键,按照加入时间升序排列。
  • 最后遍历所有 Symbol 键,按照加入时间升序排列。

    5.Object.getOwnPropertyDescriptors方法,返回指定对象所有自身属性(非继承属性)的描述对象

    6.__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()

   7.super 指向当前对象的原型对象,super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错

   8.object.defineProperty(obj,propert,description)

21.decorator 修饰器,对类进行修改,修饰器本质就是编译时执行的函数

 22.module (输入的接口为只读属性)

         1.es6 模块是静态加载,在编译时加载,意味者在编译时确定了模块的依赖关系,及输出输入变量,因此不存在判断是否加载的该模块的语句和加载的模块必须明确指定,暴露的是接口,common.js动态加载,即运行是加载,本身暴露的是对象,

          2.export 对外提供的是接口 export var m 或者export { m as n}   值是动态绑定,改变后暴露的值也改变,不同与common.js的缓存机制

           3.import 输出的变量为基本值为只读的,因为import 本质是输入接口,引用型变量可以

          4.import 'test.js' 执行加载的模块,相当于common.js  require('test')

          5.import  *  as  test   from test  全部输出加载(整体加载),平时只是加载指定的输入,不同于common.js将对象暴露,引用里面的属性,   不允许改变输出的变量值 ,

         6.export default test    默认接口,当找不到指定接口时取该接口,方便引用模块随意取名接口 ,只有一个输出接口 ,import 不要大括号,输出多个接口需要{ }  可以看做所有的接口在一个对象中,扩展引入。后面不需要跟变量声明语句  import _ {test } from test   默认和指定的输入

         7.export { test} from test    先引入后输出   当前模块不能引用test 接口,通过该方式可以继承其他的模块,export * from main

           同时输出自己的接口就可以,该*不输出默认的接口

       8. common.js模块的顶层this指向当前模块 ,es6 为undefined

      9.注意模块相互引用之间的问题,已引用一次在在引用一次时,会认为接口已输出,存在不完整

23.es6和common.js 模块的不同

          1. common.js 输出的值是一个拷贝 ,es6模块输出的值是一个引用  ,应为common.js的缓存机制,通过函数执行可以解决,es6为动态引用,不会缓存,到加载里的模块里取值

           2.es6静态加载  commo.js动态加载 

        试验阶段 在node里运用import和export  将文件名改为.mjs

     3.es6与common.js之间模块的引用遵循各自的特点,在es6下 import common.js模块等同于 引入{default :module.exports},module.exports 等同于 export default xxxxx,common.js缓存机制一样存在 ;   common.js引用es6,将其输出的接口转为对象,存在相似  ,不过还是使用import   export 风格   得到的输入接口模式为

{

get foo(){return foo}

get bar(){return foo}

} 从中看出只读属性,引入的规则

          4.import 引入common.js模块因模块是运行时才确定输出的接口,es6在编译时确定,故不能import { readFile } from 'fs'   ,改为import * ,其中的接口为指定的,不为默认的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值