es6笔记
2.let
3.块级作用域(只对变量比较严格 ,对函数的处理相当于var声明变量)
4.const
const
只能保证这个指针是固定的,不可改变指针指引,地址内的值可变,const的作用域与let命令相同:只在声明所在的块级作用域内有效,跟let一样
5.
6.变量解构赋值(遍历)
7.字符扩展(处理字符大于0xffff的字符)
codepointat()可以处理二字节以上字符, codePointAt方法会正确返回 32 位的 UTF-16 字符的码点 codePointAt方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下
String.fromCodePoint方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode方法的不足 定义在string对象上
at()返回指定为的字符 chartAt()
8.模板字符
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 中只要使用尾递归,就不会发生栈溢出,相对节省内存
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。es5使用时的环境对象
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
(5)除了
this
,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments
、super
、new.target
。上面五点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。
10 symbol 返回的是一个值
2.Symbol 值作为对象属性名时,不能用点运算符,点运算符后面总是字符串,所以不会读取
mySymbol
作为标识名所指代的那个值,导致
属性名实际上是一个字符串,而不是一个 Symbol 值。
4.symbol值不能与其他类型的值进行运算,symbol的值可以显示的转换为字符串和布尔值(symbol.tostring()显示),不能转换为数值
5.可以遍历symbol属性的有getownpropertysymbols和reflect.ownkeys
6.魔术字符串指的是,某一个具体的字符串或者数值。应该尽量消除魔术字符串,改由含义清晰的变量代替
11.set map 新的数据结构
...
)内部使用for...of
循环 Map 值值对的数据存储 set get has delete clear
11.proxy 代理 (注意this指向不确定性,指向proxy实例)对返回的实例操作,不应对代理的对象操作,不会改变代理对象
12. refelct 将object对象语言内部的方法映射出来 ,也可以修改 不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为
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)
receiver
,那么Reflect.set
会触发Proxy.defineProperty
拦截13. iterator (处理不同数据结构时的一种同一的规范)
14.generator 生成器 * 只有调用next方法才执行 任何数据结构只要有 Iterator 接口,就可以被yield*遍历
15.异步编程
事件监听
发布/订阅
Promise 对象
16.class(只是一种语法糖,本质还是构造函数)(this 很重要,谁有this权(this指向谁)就可以有权调用属性和方法)
prototype
属性上面
new.target
指向当前正在执行的函数)。如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的
17.arraybuffer ArrayBuffer对象、TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口
18.promise
catch
方法指定的回调函数,会接着运行后面那个then
方法指定的回调函数。如果没有报错,则会跳过catch
方法
19.async
20.object
1. object.is(val,val)判断二个val是否相等,解决了NaN不等于自身的问题,-0不等于+0
2.object.assgin(target,source) 对象合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),返回目标对象,拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性
3. Object.getOwnPropertyDescriptor(object,属性)
方法可以获取该属性的描述对象,得到数值属性
目前,有四个操作会忽略enumerable
为false
的属性,实际上,引入“可枚举”(enumerable
)这个概念的最初目的,就是让某些属性可以规避掉for...in
操作,不然所有内部属性和方法都会被遍历到,ES6 规定,所有 Class 的原型的方法都是不可枚举的。
for...in
循环:只遍历对象自身的和继承的可枚举的属性。Object.keys()
:返回对象自身的所有可枚举的属性的键名。JSON.stringify()
:只串行化对象自身的可枚举的属性。Object.assign()
: 忽略enumerable
为false
的属性,只拷贝对象自身的可枚举的属性。
(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 * ,其中的接口为指定的,不为默认的