关于es6:es6笔记

8次阅读

共计 4815 个字符,预计需要花费 13 分钟才能阅读完成。

let 和 const

应用 var 带来的问题

var 净化全局变量

var a=1;
console.log(window.a)

var 会使变量晋升

console.log(a) // undefined
var a=1;

var 能够被反复申明

var a=1;
var a=2;
var a=3;

var 作用域问题

全局作用域

{var a=1;}
console.log(a) // 1

{let b=2;}
console.log(b) // b is not defined

函数作用域

for(var i=0;i<3;i++){setTimeout(()=>console.log(i),0) // 3,3,3
}
for(let i=0;i<3;i++){setTimeout(()=>console.log(i),0) // 0,1,2
}

const 常量

const 指向地址不变

开展运算符

合并对象或数组

合并数组

let a=[0,1];
let b=[2,3];
console.log([...a,...b]) //[0, 1, 2, 3]

合并对象

合并对象要辨别是深拷贝还是浅拷贝,开展运算符只拷贝对象一层,属于浅拷贝

let team={name:"Lakers",location:{city:"Los Angeles"}};
let player=["LeBron","Davis"];
let kuzma = {age:25};
let coach = {name:"Frank Vogel",age:47};

let Lakers = {
    ...team,
    ...coach,
    player:[...player,kuzma]
}

team.name="change";    // Lakers 批改失败,浅拷贝
team.location.city = "change"; // Lakers 批改胜利,援用地址未变

console.log(Lakers)

实现深拷贝

1、持续开展

let Lakers = {
    team:{
        ...team,
        location:{...team.location}
    },
    ...coach,
    player:[...player,kuzma]
}

2、对象转字符串再转对象,这种形式有个缺点,会疏忽掉值为 undefined 的属性

Lakers = JSON.parse(JSON.stringify(Lakers))

3、实现深拷贝办法

// 判断类型:typeof、instanceof、Object.prototype.toString.call、constructot
function deepClone(obj){
    // 不是对象间接返回
    if(obj == null) return obj;
    if(obj instanceof Date) return new Date(obj);
    if(obj instanceof RegExp) return new RegExp(obj);
    if(typeof obj !== "object") return obj;

    // 可能是数组或对象
    let cloneObj = new obj.constructor;
    for(let key in obj){if(obj.hasOwnProperty(key)){
            // 递归赋值
            cloneObj[key] = deepClone(obj[key]);
        }
    }

    return cloneObj
}

Set 和 Map

Set

let s1 = new Set([0,1,2,0,2]);
let s2 = new Set([2,3,3,4,5]);

// 并集
function union(){let merge = [...s1,...s2];
    return [...new Set(merge)]
}

// 交加
function intersection(){return [...s1].filter(item=>s2.has(item));
}

// 差集 s1=>s2
function diff(){return [...s1].filter(item=>!s2.has(item));
}

Map

Mapkey 值,不能反复,WeakMapkey 必须是对象类型

let wm=new WeakMap();
let obj = {name:"124"};
wm.set(obj,"test");
obj = null;
console.log(wm) // 清空 obj,这个空间依然存在 m
/* WeakMap
* [[Entries]]
* 0: {{name: "124"} => "test"}
*/

利用 WeakMap 优化 深拷贝函数:

function deepClone(obj,hash = new WeakMap()){if(obj == null) return obj;
    if(obj instanceof Date) return new Date(obj);
    if(obj instanceof RegExp) return new RegExp(obj);
    if(typeof obj !== "object") return obj;
    
    // 如果是对象并存在 weakMap 中,阐明拷贝的对象曾经存在了,间接返回
    if(hash.has(obj)) return hash.get(obj);

    let cloneObj = new obj.constructor;
    
    // 保留拷贝的对象到 WeakMap 中
    hash.set(obj,cloneObj);

    for(let key in obj){if(obj.hasOwnProperty(key)){cloneObj[key] = deepClone(obj[key],hash);
        }
    }

    return cloneObj
}

Object.defineProperty

对象自带的 gettersetter:

let obj = {
    value:"124",
    get name(){console.log("get")
        return this.value
    },
    set name(val){console.log("set")
        this.value = val;
    }
}

console.log(obj.name)
obj.name="test";
console.log(obj.name)

利用 Object.defineProperty 实现数据劫持

let update = () => console.log("update");

let team = {
  name: "Lakers",
  player:["lbj","ad"],
  location: {city: "Los Angeles"}
};

observer(team);

function observer(obj) {if(typeof obj !== "object") return obj;
  for(let key in obj) {defineReactive(obj, key, obj[key]);
  }
}

function defineReactive(obj, key, value) {observer(value);
    Object.defineProperty(obj,key,{get(){return value},
        set(newVal){if(newVal === value) return;
            update();
            observer(newVal); // 新值也有可能是对象
            value = newVal
        }
    })
}

// 数组操作无奈劫持,重写无奈劫持的数组办法
const Methods = ["push","pop","shift","unshift","slice","sort","reverse"];
Methods.forEach(method=>{
    // 面向切面开发,装璜器
    const oldMethod = Array.prototype[method];
    Array.prototype[method] = function(){update();
        oldMethod.apply(this,arguments)
    }
});

team.name="la";
team.location.city = "change";
team.player.push("kz")

箭头函数

箭头函数没有 thisarguments

Proxy

  • Object.defineProperty 劫持不到数组的更新(push、pop、shift、unshift)
  • Proxy 能够监测到数组和对象的变动
  • Proxy 监测数组变动时,要留神数组长度的变动也会被监测到,这时手动扭转数组会出问题
let update = ()=>console.log("update");

let arr = [1,2,3];
// Proxy 能够监测到数组和对象的变动
// 数组的变动会先扭转数组的内容,还会扭转数组的长度
let proxy = new Proxy(arr,{set(target,key,value){
        // 不要手动操作数组,因为数组变动时,可能调用 push 或 pop 扭转数组长度,这时 key 值会出问题
        if(key == "length") return true;
        update();
        return Reflect.set(target,key,value);
    },
    get(target,key){return Reflect.get(target,key);
    }
})

proxy.push("4");
console.log(proxy)

数组罕用办法

  • es5 forEach reduce map filter some every
  • es6 find findIndex
  • es7 includes

reduce 常见用法

求和

// 购物车
let cart = [{price:10,count:2},
    {price:20,count:3},
    {price:19.9,count:2},
    {price:14.5,count:1}
];

// 求购物车总价格
let totalPrice = cart.reduce((total,item)=>total+item.price*item.count,0
);

合并数据

let keys = ["name","age"];
let value = ["kobe",18];

let result = keys.reduce((obj,key,index)=>{obj[key]=value[index]
        return obj;
    },{});

compose 办法

function sum(a,b) {return a+b};

function toUpper(str){return str.toUpperCase();
}

function log(target){console.log(target)
}

compose(sum,toUpper,log)("chen","wl");

function compose(...middlears){//return middlears.reduce((a,b)=>(...args)=>b(a(...args)))
    return (...args)=>{let fn = middlears.shift();
        middlears.reduce((a,b)=>{return b(a)
        },fn(...args));
    }
}

reduce 简略实现

Array.prototype.reduce = function(fn,prev){let target = deepCopy(this);
    let total = prev || target.shift();

    target.forEach((next,i)=>{total = fn(total,next,i,target);
    });
    return total;
}

let result = [1,2,3,4].reduce((a,b)=>a+b);
console.log(result)

function deepCopy(obj){if(obj == null) return obj;
    if(typeof obj !== "object") return obj;
    let newObj = new obj.constructor;
    for(let key in obj){newObj[key] = deepCopy(obj[key])
    }
    return newObj;
}
正文完
 0