1. var 特点
- 存在变量声明提升;
- 可重复声明变量;
- 全局变量挂载到window。
2.let
- 不会存在变量声明提升;
- 不能重复声明变量;
- 全局变量不会挂载到window;
- {}内形成块级作用域,产生临时死区,外部同名变量不能使用。
3. const
- 常量声明,声明时必须赋值且不能改变。
- 存储常量的空间里面的值不能改变。
const PI = { } PI.name = 20不会报错,这里修改的是对象中的值。 - 其余特点与let相同。
4. 拓展运算符+克隆
funcition sum(...arg){
let sumNumber = 0;
arg.forEach(function(ele){
sumNumber += ele;
});
return sumNumber;
}
sum(1,2,5,7)
浅克隆1:
let obj1 = {
name: 'cg'
}
let obj2 = {
age:18
}
let obj3 = {
...obj1, //浅克隆
...obj2
}
浅克隆2:Object.assign(targetObj,obj1,obj2)
深克隆1:
let obj1 = {
name: 'cg',
leader:{
age:20
}
}
let obj2 = {
sex:famale
}
let obj3 = {
...obj1,
leader:{ //深克隆
...leader
},
...obj2
}
深克隆2:var obj = Json.parse(Json.stringify(obj1))
该方法的问题:
- 无法实现对函数、正则等特殊对象的克隆
- 会抛弃对象的constructor,所有构造函数会执行Object
- 对象有循环引用就会报错
5.destructring 解构
let obj = {
name:'cst',
age:18
}
let{ name , age } = obj; //解构
let{ name: oName, age: oAge , sex = 'male'} = obj; //解构
let { direct ,gut , mainActor, srceenwriter} = res.data; //解构
6.箭头函数
作用:函数目的指向性更强,可读性更好,简化代码,提升开发效率。
let sum = (a,b)=> a + b
特点:
-
不用写function关键字;
-
只能作为函数使用,不能做构造函数,没有原型。
-
函数形参不能重复;
-
返回值可以不写return,但是有时需要配合
{}; -
内部
arguments this由定义时外围最接近一层的非箭头函数的arguments 和 this决定。let obj ={ ms:'ab', fn(){ setTimeout()=>{ console.log(this.msg) //此处箭头函数this指向obj } } } obj.fn()
7.object.defineProperty
vue3.0- 数据双向绑定原理:object.defineProperty
object.defineProperty不能直接对数组进行设置,vue使用重写数组方法’
Object.defineProperty{obj,'name',{
value:'cst',
writable:false,
configurable:true,
enumerable:true,
get:function(){
return tem
}, //get/set 与value和writable 不能同时使用
set:function(val){
tem = val;
}
}}
var obj = {
var tem= '';
get name (){
return tem
},
set name (newval){
tem = enwval;
}
}
数据劫持,
let oDiv = document.getElementById('show');
let oinput = document.getElementById('demo');
let oData = {
prev: {
name: 'marzot'
},
value: 'dizhongdi'
};
oinput.oninput = function () {
oData.value = this.value;
}
let updata = () => oDiv.innerText = oData.prev.name;
updata();
监控对象属性是否改变
let Observer = (data) => { //传入Odata对象
if (!data || typeof data != 'object') {
return data;
};
Object.keys(data).forEach(function (keys) {
//枚举对象的属性,然后循环操作
definedRective(data, keys, data[keys]) //对象,属性,val
});
}
let definedRective = (data, keys, val) => {
Observer(val);//嵌套对象进行递归枚举。
Object.defineProperty(data, keys, {
get: function () {
return val;
},
set: function (newVal) {
if (newVal == val) return;
val = newVal;
updata();
}
})
}
Observer(oData);
oData.value = 'asgaga124154151515';
oData.prev.name = 'beiduofen';
8.proxy
proxy可以对新增的属性进行代理。Object.defineProperty不行。
let odata = {
name: 'laowang',
sex:{
age:18
}
}
let newdata = new Proxy (odata,{
set(target,key ,val ,receiver){
Reflect.set(target,key,val);
updata();
},
get(target,key,receiver){
return Reflect.get(target,key);
},
has(target,key){
}
})
function updata(){
console.log('更新了')
9.Class+继承
1.圣杯模式:
function Father(){}
function Son(){}
Father.prototype.lastName=‘Jack‘;
//圣杯模式
function inherit(Target,Origin){
function F(){};
F.prototype=Origin.prototype;
Target.prototype=new F();
}
inherit(Son,Father);
var son=new Son();
var father=new Father();
Son.prototype.sex=‘male‘;
console.log(son.lastName);//Jack
console.log(son.sex);//male
console.log(father.sex);//undefined
2. __proto__
Son.prototype.__proto__ = Father.prototype;
3. ES6API
Object.setPrototypeOf(Son,Father);
(需要降级浏览器才支持)
4. Class
class Foo{
static age = 'l00' //静态属性
static fly(){ //静态方法
console.log('fly')
}
constructor(name){
this.name = name|| '攻击机'; //私有属性
this.blood = 100
}
biu(){
console.log('biubiubiu') //原型方法/公有方法
}
}
//实例
var foo1 = new Foo('攻击机1');
var foo2 = new Foo('攻击机2')
//测试
Foo.fly()//fly ->静态方法只属于类本身
console.log(Foo.age)//100 ->静态属性只属于类本身
console.log(foo1.name)//攻击机1 ->私有属性
console.log(foo2.name)//攻击机2 ->私有属性
console.log(foo1.blood)//100 ->私有属性
console.log(foo2.blood)//100 ->私有属性
foo1.biu()//biubiubiu ->原型方法
foo2.biu()//biubiubiu ->原型方法
//继承
class Boom extends Foo{
constructor(name){
super(name) //继承了私有属性
}
}
//实例
var boom1 = new Boom('轰炸机')
//测试
Boom.fly()//fly ->继承父类的静态方法
console.log(Boom.age)//100 ->继承父类的静态属性
console.log(boom1.blood)//100 ->继承父类的私有属性
console.log(boom1.name)//轰炸机 ->继承父类的私有属性
boom1.biu()//biubiubiu ->继承父类的原型方法
Class特点:
- 必须new;
- 不能枚举;
- 静态属性无法被实例继承,可以被super调用,可以被子类继承。
5.ES7-Class
需要配合插件 @bable/plugin-proposal-class-properties使用
静态属性 static num = 10
私有属性 property= 'xxx'
10. ES7-decorator
@ fn //装饰器 写在需要装饰的属性前面
function fn(proto,key,description){
description.writable = false;
description.initializer = function(){ //修饰静态属性时initializer 修饰原型方法时为value
//可以在这里做数据劫持
return 'value';
}
}
11. set
- 值唯一;
- 没有属性名,只有属性值;
用途:可以转成数组,其本身具备去重。交集。并集。差集的作用
let os = new Set(1,2,[44,84],true,{name:leo})
方法:
os.add(1,5,10)//添加值
os.delete(1)//删值
os.clear()//清空
os.has(1)//判断有无1
os.forEach(ele,val)=>{
//遍历
}
for(let prop of os){ //for of 遍历
console.log(prop)
}
应用场景:
数组转化:
let os = new Set(arr);
Array.from(os)//转换成数组
[...os]//拓展为数组
求并集
let arr1 = [1,2,5,8,];
let arr2 = [5,8,1,9];
let os = new Set(...arr1,...arr2);
求交集
let os1 = new Set(arr1);
let os2 = new Set (arr2);
let newArr = [...os1].filter(ele=>os2.has(ele))
求差
let os1 = new Set(arr1);
let os2 = new Set(arr2);
let newArr1 = [...os1].filter(ele=>!os2.has(ele))
let newArr2 = [...os2].filter(ele=>!os1.has(ele))
let newArr = [...newArr1,...newArr2]
12. map
let oMap = new Map()
方法:
oMap.get('name')//取值
oMap.set('name','leo')//赋值
oMap.delete('name')//删值
oMap.clear()//清空
oMap.size()//长度
oMap.forEach(key,value,self)=>{}//遍历
oMap.keys()//属性名
for(let prop of oMap){ //for of 遍历
console.log(prop[0])
}
Map原理
function myMap() {
this.bucketLength = 8;
this.init();
}
myMap.prototype = {
init: function () {
this.bucket = new Array(this.bucketLength);
for (var i = 0; i < this.bucket.length; i++) {
this.bucket[i] = {
type: 'bucket_' + i,
next: null
}
}
},
makeHash: function (key) {
let hash = 0;
if (typeof key !== 'string') {
if (typeof key == 'number') {
hash = Object.is(key, NaN) ? 0 : key;
} else if (typeof key == 'object') {
hash = 1;
} else if (typeof key == 'boolean') {
hash = Number(key);
} else {
hash = 2;
}
} else {
for (let i = 0; i < 3; i++) {
hash += key[i] ? key[i].charCodeAt(0) : 0;
}
}
return hash % 8;
},
set: function (key, value) {
let hash = this.makeHash(key);
let oTempBucket = this.bucket[hash];
while (oTempBucket.next) {
if (oTempBucket.next.key == key) {
oTempBucket.next.value = value;
return;
} else {
oTempBucket = oTempBucket.next;
}
};
oTempBucket.next = {
key: key,
value: value,
next: null
};
},
get: function (key) {
let hash = this.makeHash(key);
let oTempBucket = this.bucket[hash];
while (oTempBucket) {
if (oTempBucket.key == key) {
return oTempBucket.value;
} else {
oTempBucket = oTempBucket.next;
}
}
return undefined;
},
delete: function (key) {
let hash = this.makeHash(key);
let oTempBucket = this.bucket[hash];
while (oTempBucket.next) {
if (oTempBucket.next.key == key) {
oTempBucket.next = oTempBucket.next.next;
return true;
} else {
oTempBucket = oTempBucket.next;
}
}
return false;
},
has: function (key) {
let hash = this.makeHash(key);
let oTempBucket = this.bucket[hash];
while (oTempBucket) {
if (oTempBucket.next && oTempBucket.next.key == key) {
return true;
} else {
oTempBucket = oTempBucket.next;
}
}
return false;
},
clear: function (key) {
this.init();
}
}
let oMp = new myMap();
let obj1 = {
name: 'cst'
}
oMp.set('name1', 'cst1');
oMp.set('name2', 'cst2');
oMp.set(obj1, '---');
oMp.set(obj1, '+++');
oMp.set(function () { }, true);
13.promise
1.异步编程:
定时器、事件、ajax 、文件读取。
异步编程的问题:
- 异步编程避免不了回调。易产生回调地狱,难于维护和扩展。
- try catch 只能捕获同步代码中出现的异常。
- 同步并发的异步存在一定的问题。
管理回调的方法:
jquery callbackLoadsh afterpromisegeneratorasync await
2.promise使用
let op = new Promise((resolve,reject)=>{ //同步执行
})
op.then(()=>{},()=>{}) 异步执行 promise内部为微任务,有优先执行权,定时器,ajax为宏任务,会优先进入执行栈,但是会在promise后执行。
3.链式操作法则
let op = new Promise((resolve,reject)=>{})
op.then(()=>{
},()=>{
}).then(()=>{ //链式操作
},()=>{
})
- 上一个promise不抛出错误时,下一个then执行resolve函数;
- 上一个promise抛出错误时,下一个then执行reject函数;
- 返回值可以作为下一个then注册函数的执行参数;
- 当返回值是 new promise对象时,下一个执行函数由new promise对象内部执行的函数决定。
4.API
promise.all([promise1,promise2,promise3]).then((resolve)=>{
//三个promise对象都执行成功时,then执行成功回调函数
},(reject)=>{
//有一个promise对象执行失败时,then执行失败回调函数
})
promise.race([promise1,promise2,promise3]).then((resolve)=>{
//有一个执行成功时,then执行成功回调函数
},(reject)=>{
//所有promise对象执行失败时,then执行失败回调函数
})
5. promise实现
function MyPromise (executor) {
var self = this;
self.status = 'pending';
self.resolveValue = null;
self.rejectReason = null;
self.ResolveCallBackList = [];
self.RejectCallBackList = [];
function resolve (value) {
if (self.status === 'pending') {
self.status = 'Fulfilled';
self.resolveValue = value;
self.ResolveCallBackList.forEach(function (ele) {
ele();
});
}
}
function reject (reason) {
if (self.status === 'pending') {
self.status = 'Rejected';
self.rejectReason = reason;
self.RejectCallBackList.forEach(function (ele) {
ele();
});
}
}
try {
executor(resolve, reject);
}catch(e) {
reject(e);
}
};
function ResolutionRetrunPromise (nextPromise, returnValue, res, rej) {
if (returnValue instanceof MyPromise) {
// Promise 对象
returnValue.then(function (val) {
res(val);
}, function (reason) {
rej(reason)
});
}else {
res(returnValue);
}
}
MyPromise.prototype.then = function (onFulfilled, onRejected) {
if (!onFulfilled) {
onFulfilled = function (val) {
return val;
}
}
if (!onRejected) {
onRejected = function (reason) {
throw new Error(reason);
}
}
var self = this;
var nextPromise = new MyPromise(function (res, rej) {
if (self.status === 'Fulfilled') {
setTimeout(function () {
try {
// var nextResolveValue = onFulfilled(self.resolveValue);
// res(nextResolveValue);
var nextResolveValue = onFulfilled(self.resolveValue);
ResolutionRetrunPromise(nextPromise, nextResolveValue, res, rej);
}catch(e) {
rej(e);
}
}, 0);
}
if (self.status === 'Rejected') {
setTimeout(function () {
try {
var nextRejectValue = onRejected(self.rejectReason);
ResolutionRetrunPromise(nextPromise, nextRejectValue, res, rej);
}catch(e) {
rej(e);
}
}, 0);
}
//
if (self.status === 'pending') {
self.ResolveCallBackList.push(function () {
try {
var nextResolveValue = onFulfilled(self.resolveValue);
ResolutionRetrunPromise(nextPromise, nextResolveValue, res, rej);
}catch(e) {
rej(e);
}
});
self.RejectCallBackList.push(function () {
setTimeout(function () {
try {
var nextRejectValue = onRejected(self.rejectReason);
ResolutionRetrunPromise(nextPromise, nextRejectValue, res, rej);
}catch(e) {
rej(e);
}
}, 0);
});
}
});
return nextPromise;
};
MyPromise.race = function(promiseArr) {
return new MyPromise(function (resolve, reject) {
promiseArr.forEach(function (promise, index) {
promise.then(resolve, reject);
});
});
};
14.generator 生成器
let obj = {
0: "a",
1: "b",
2: "c",
length: 3,
[Symbol.iterator]: function* () {
let curIndex = 0;
while (curIndex != this.length) {
yield this[curIndex];
curIndex++;
}
}
};
console.log([...obj])