普通函数和箭头函数的区别:
箭头函数没有prototype(原型),所以箭头函数本身没有this
箭头函数的this在定义的时候继承自外层第一个普通函数的this。
如果箭头函数外层没有普通函数,严格模式和非严格模式下它的this都会指向window(全局对象)
箭头函数本身的this指向不能改变,但可以修改它要继承的对象的this。
箭头函数的this指向全局,使用arguments会报未声明的错误。
箭头函数的this指向普通函数时,它的argumens继承于该普通函数
使用new调用箭头函数会报错,因为箭头函数没有constructor
箭头函数不支持new.target
箭头函数不支持重命名函数参数,普通函数的函数参数支持重命名
箭头函数相对于普通函数语法更简洁优雅.
箭头函数的注意事项及不适用场景
箭头函数的注意事项:
箭头函数一条语句返回对象字面量,需要加括号
箭头函数在参数和箭头之间不能换行
箭头函数的解析顺序相对||靠前
不适用场景:箭头函数的this意外指向和代码的可读性。
对象{fn: () => {this指向window}}
window.addEventListener('click', () => {this指向全局})
promise
- 状态
pending (等待态)
fulfilled (完成态)
rejected (拒绝态)
- then
then 方法返回一个 promise 对象
若 onFulfilled 、onRejected 返回一个非promise对象、非thenable对象的值 x ,则 promise2 的状态为 fulfilled ,终值为 x
若 onFulfilled 、onRejected 返回一个 promise 对象的值 x ,promise2 的状态、终值、拒因与 x 同步
若 onFulfilled 、onRejected 返回一个 thenable 对象 ,会对 thenable 对象进行展开操作,promise2 的状态、终值、拒因取决于 thenable 对象的 then 方法调用结果
若 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 的状态为 rejected,拒因为 e
- 终值和拒因的穿透特性
如果 promise 的状态变为 fulfilled,then 方法没有注册 onFulfilled
then 方法返回的 promise 对象的状态变为 fulfilled
then 方法返回的 promise 对象的终值与原 promise 对象的终值相同
如果 promise 的状态变为 rejected,then 方法没有注册 onRejected
then 方法返回的 promise 对象的状态变为 rejected
then 方法返回的 promise 对象的拒因与原 promise 对象的拒因相同
(1)
const promise = new Promise((resolve, reject) => {
resolve('success1')
reject('error')
resolve('success2')
})
promise
.then((data) => {
console.log(data)
})
.catch((err) => {
console.log(err)
})
结果:success1
(2)
new Promise((resolve,reject)=>{
console.log(3);
let p = new Promise((resolve, reject)=>{
console.log(7);
setTimeout(()=>{
console.log(5);
resolve(6);
},0)
resolve(1);
});
resolve(2);
p.then((arg)=>{
console.log(arg);
});
}).then((arg)=>{
console.log(arg);
});
console.log(4);
结果:1
(3)
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
结果:3 7 4 1 2 5
(4)
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
结果:1 2 4 3
(5)
Promise.resolve(1)
.then((data) => {
console.log(data)
return 2
})
.catch((err) => {
return 3
})
.then((data) => {
console.log(data)
})
结果:1 2
https://juejin.im/post/5cf65860e51d4556be5b3a11#heading-0
es6各知识点汇总
const let
存在暂时性死区
不存在变量提升
不允许重复定义
const是指定的地址不变,所以对于基本数据类型是不变的,对于引用类型是可以改变其中的key值的,如果需要可以Object.freeze(obj)循环冻结
在{}内是块级作用域范围, 可以声明函数,以前是只有在顶级作用域和函数中定义函数。
var和function定义会挂载到window上成为全局对象属性,单let、const、class不会
解构
只要是iterator就可以解构数组
可以设置默认值,只有严格等于undefined才会使用默认值,同时要注意默认值不要使用未定义的变量
结构的右侧必须是数组和对象,数组按照index位置解构,对象按照key、val解构。如果右侧不是数组和对象会转化成对象,但是undefined和null转化不了,所以会报错
解构不到返回undefined
可以按照导出模块来结构 import {a,b} from
字符串
str='123'
str.padStart(5, 'wer') // 从前重复补全1到str有5个长度
str.padEnd(5, '1') // 从后重复补全1到str有5个长度
str.startWidth('5', 1) // 从前index=1开始找5是否以它开头
str.endWidth('5', 1) // 从后index=length - 1开始找5是否以它结尾
str.trim() // 消除两头空格
str.trimStart() // 消除头部空格
str.trimEnd() // 消除尾部空格
str.includes('5', 1) // 从index=1开始找是否包含5
数值
Math.trunc(1.1111) // 1返回整数部分负数返回负整数部分
Math.sign(1.2) // 1返回正负1或者NAN
Number.isfinite(23) // true判断是否有限
Number.isInteger(2.0) // true 是否是整数
Number.EPSILON // 最小常量,1到大于1的最小浮点数之差
函数
fn = (a=1, b=2) => {},可以使用参数默认值,但fn.length会失真
fn = (...args) => {} 可以使用rest结构,但只能在参数的最后
数组
Array.from(类数组, mapFn) 转化成数组
Array.of(1,2,3) 转化成数组
Array.flat(展开层级) // 数组平铺展开
Array.flatMap(x => {}) // 数组先map再平铺展开
arr.keys() // key值组合
arr.values() // value的iterator需要for of遍历
arr.entries
arr.copyWithin(覆盖开始(含), 拷贝开始(含),拷贝结束(不含)),负数是倒数
arr.find(mapFn, context) 回调函数的上下文
arr.findIndex()
arr.fill() 填充
对象
Object.assign(obj) 浅拷贝
表达式作为属性名{[a + 1]: 1111}
Object.is(0, -0) //false 判断是否相等,NaN 和NaN是相等的
Object.getOwnPropertyNames(obj) // 获取所有自己的属性,除了Symbols
Object.keys(obj, str) // 获取自己的所有可枚举属性,symbols除外 [k1, k2],如果参数是number, boolean,返回空数组,如果是null, undefined报错
Object.values(obj) // 没有iterator说以返回数组values的数组 [v1, v2]
Object.entries(obj) // [[k1, v1], [k2, v2]] 二维数组
for (let k in obj) // 获取自己和继承的所有属性, symbols除外
Object.getOwnPropertySymbols(obj) // 获取所有Symbols属性
Reflect.ownKeys(obj) // 自身所有属性
Object.getOwnPropertyDescriptor(obj, 'a') 获取属性描述信息
Object.getOwnPropertyDescriptors(obj) 获取所有属性的描述对象
Object.setPropertyOf(o1, o2) 把o1的原型设置为o2,等同于 o1.proto = o2
Object.getPropertyOf(o1) 读取原型对象
Super 执行对象的原型对象, 只能用在对象的方法中
{
chain () {return super.a}
}
Symbol
唯一
不能被for in,for of, Object.keys(), Object.getOwnPropertyNames(), JSON.stringify() 获取
-
let s1 = Symbol('s1')
s1.description // s1 获取描述信息
let s2 = Symbol.for('12') // 搜索有没有这个symbol,有则返回,没有则创建再返回
let s1 = Symbol.for('12') // s1 === s2
Fymbol.keyFor(s1) // 获取被Symbol.for注册过的描述信息,和description返回的值相同
-
istanceof判断是否是一个对象的实例的时候调用该对象的内置的方法[Symbol.hasInstance], 可以解决 ‘’ instanceof String 为false的问题
Class MyClass {
[Symbol.hasInstance] (arr) { return true }
}
[] instanceof new Myclass() // true
Set 和 Map
let s1 = new Set([k1,k2,k3]) 和 let m1 = new Map([[k1, k2], [k3,k4]]) // 接收的参数是iteable的对象,不能接类数组,因为没有iterator
s1.add(k) / m1.set(k, val)
s1.get(k) / m1.get(k)
s1.has(k) / m1.has(k) 返回boolean,表示是否含有k
s1.size / m1.size
s1.delete(k) / m1.delete 返回boolean标识是否删除成功
s1.clear() m1.clear()
s1.forEach(item => {}) / m1.forEach(item => {})
s1.keys() / m1.keys()
s1.values() / m1.values()
-s1.entries() / m1.entries // 这些方法是Object对象上的,如果是iterator的类型就有,如果不是只能调用Object.keys(canshu) 这种形式
- Array.from(new Set([1,2, 1, 3])) // 去重之后转成数组
Proxy
this指向proxy对象不指向代理对象
可以作为原型对象 Object.create(new Proxy(target, handler)), new (new Proxy(fn, handler))
let {proxy, revoke} = Proxy.revocable(target,handler); revoke()可以回收拦截
let p = new Proxy({a: 2, b: 4}, {
get (target, key, proxySelf) {},
set (target, key, value, proxySelf) {},
has (target, key) {}, // 拦截 in 操作符,对for in 不起效
construct (target, args, proxySelf) {}, // 拦截new
deleteProperty (target, key) {}, // 拦截delete
defineProperty (target, key, proxySelf) {}, // 拦截Object.defineProperty操作
getOwnPropertyDescriptor (target, key, proxySelf) {}, // 拦截Object.getOwnPropertyDescriptor()
getPropertyOf (target) {}, // 拦截获取对象原型 就是下面这些操作:
Object.prototype.__proto__
Object.prototype.isPropertyOf()
Object.prototype.getPropertyOf()
Object.prototype.setPropertyOf()
instanceof
isExtensible (target) {}, // 拦截Object.isExtensible
ownKeys (target) {}, // 拦截获取自身属性
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
for in
preventExtensions (target) {}, // 拦截Object.preventExtensions()
setPropertyOf (target, proto) {}, // 拦截Object.setPrototypeOf()
})
Reflect
class 和 extend
this指向实例
如果没有设置contructor,会自动增加一个constructor,其中返回一个this
可以用Object.getPropertyOf(child)
super作为对象使用时,在普通方法中指向父类原型,在静态方法中指向父类
通过super调用父类的方法时,this指向子类
Class Person () {
b = 123 // 在对象的实例上
constructor (a) {
this.a = a
}
say () { // 在Person.prototype上
console.log('say')
}
}
class child extends Person {
constructor (...args) {
super(...args)
}
}
导入导出
export const a = 1
export {a,b,c}
export default {}
import {a as a1} from ''
import * as obj from ''
import whatever from ''
多次导入一个文件,只会执行一次
import在编译时执行,不是在运行时执行
import存在变量声明提升,所以import不要和require时使用,还对其有依赖