es6劃重點
es6劃重點
1.作用域變數
1.1.let
和var
對比
1.變數不提升
var
可能會造成變數提升
這裡變數提升了,先宣告a
然後列印再賦值,結果是undefined
console.log(a);//undefined var a = 1; //相當於 var a; console.log(a); a = 1;
let
的話,變數不會提升,列印的時候,會報錯
,因為還沒宣告
console.log(a);//a is not defined let a = 1;
2.不能重複定義
var
可能會被重新賦值,let
不能重複宣告一個變數
var a = 1; var a = 2; console.log(a);//2
let a = 1; let a = 2;//Identifier 'a' has already been declared 這裡是說它已經被聲明瞭,不能重複宣告 console.log(a);
3.暫存死區
var的作用域問題 (函式作用域 全域性作用域) (let 暫存死區)
只要塊級作用域記憶體在let
命令,它所宣告的變數就“繫結”(binding
)這個區域,不再受外部的影響。
{ let a = 1; } console.log(a);//a is not defined
{ var a = 1; } console.log(a)//1
4.閉包新寫法
以前
;(function () { })();
現在
{}
2.const(常量)
const
宣告一個只讀的常量。一旦宣告,常量的值就不能改變。
const
命令宣告的常量
也是不提升
,同樣存在暫時性死區
,只能在宣告的位置後面使用
。
const PI = 3.141593 PI > 3.0
es5寫法
Object.defineProperty(typeof global === "object" ? global : window, "PI", { value:3.141593, enumerable:true,//物件屬性是否可通過for-in迴圈,flase為不可迴圈,預設值為true writable:false,//物件屬性是否可修改,flase為不可修改,預設值為true configurable: false//能否使用delete、能否需改屬性特性、或能否修改訪問器屬性 }) PI > 3.0;
3.解構
1.陣列解構
let [,b,c,d=100] = [1,2,3]; console.log(b,d);
2.物件解構
let obj = {name:'cjw',age:18}; //這裡重新命名了 let {name:Name,age,address="預設"} = obj; console.log(Name, age, address)
3.混合解構
let [{name}] =[{name:'cjw'}];
4.傳遞引數,結果解構
Promise.all(['cjw','9']).then(([name,age])=>{ console.log(name, age); });
4.拷貝
4.1.淺拷貝
let arr1 = [1,2,3,[1,2,3]]; let arr2 = [1,2,3]; let arr = [...arr1,...arr2]; console.log(arr) arr1[3][0] = 100;
4.2.物件合併
let school = {name:'zfpx',a:{a:1}}; let my= {age:18}; let newObj = {...school,a:{...school.a},...my}; console.log(newObj)
4.3.JSON.parse(JSON.stringify())
這個只能拷貝普通物件,new Date之類不能拷貝
let school = { name: 'zfpx', a: { a: 1 } ,date:new Date(),reg:new RegExp(/\d+/),fn:function(){}}; let s = JSON.parse(JSON.stringify(school));
4.4.深拷貝(遞迴拷貝)
function deepClone(obj) { // 遞迴拷貝 深拷貝 if(obj == null) return null; if (obj instanceof Date) return new Date(obj); if(obj instanceof RegExp) return new RegExp(obj); if(typeof obj !== 'object') return obj; let t = new obj.constructor for(let key in obj ){ t[key] = deepClone(obj[key]) } return t; } let o = { a: [1, 2, 3] } let r = deepClone(o); o.a[1] = 1000
4.5.展開運算子
// 剩餘運算子只能用在最後一個引數 function test(a, b,...c) { // c = [5,6,7] // 將類陣列轉化成陣列 let d = Array.prototype.slice.call(arguments,2) // a,b,...c let e =Array.from(arguments).slice(2); let arr = [...arguments].slice(2); console.log(e); } test(1,2,3,5,6,7);
把多個物件的屬性複製到一個物件中,第一個引數是複製的物件,從第二個引數開始往後,都是複製的源物件
// Object.assign{...} let name ={name:'zfpx'} let age = {age:9} let obj = Object.assign(name,age); // {...} console.log(obj);
5. 代理proxy
5.1.普通函式(defineProperty)
Object.defineProperty(obj, 'PI', { enumerable: true, configurable: false, get(){ console.log('get'); }, set(){ console.log('set'); val = v; } }) obj.PI = 3.15;
5.2.mvvm
let obj = {name: {name: 'cjw'}, age: 18}; 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(){ console.log('update'); } }) } observer(obj); obj.name.name = 'cjw';
5.3 普通代理
let proxy = new Proxy(obj, { set(target, key, value){ if(key === 'length') return true; console.log('update'); return Reflect.set(target, key, value); }, get(target, key){ return Reflect.get(target, key); } }) proxy.push('123'); console.log(proxy.length);
5.4 多層代理
let obj = {name: {name: 'cjw'}, age : 18}; function set(obj, callback){ let proxy = new Proxy(obj, { set(target, key ,value){ if(key === 'length') return true; console.log('更新'); return Reflect.set(target, key, value); }, get(target, key){ return Reflect.get(target, key); } }) callback(proxy); } set(obj, function(proxy){ proxy.age = '100'; console.log(proxy); })
6.箭頭函式
this
指向
去掉function
關鍵字
去掉return
和{}
6.1 普通剪頭函式
function a(a) { return function (b) { return a + b; } } let a = a => b => a + b; console.log(a(1)(2));
6.2 類陣列
let a = (...arguments) => { console.log(arguments) } a(1, 2, 3);
6.3 this指向問題
// this指向問題 let obj = { a: 1, b() { // obj = this console.log(this); setTimeout(() => { // 箭頭函式中沒有this指向 從而解決了this的問題 this.a = 100; }, 1000); } } obj.b(); setTimeout(() => { console.log(obj.a) }, 2000);
6.4 let不會將變數放在window上
let a = 1000; // let不會將變數放在window上 let obj = { a: 1, b: () => { this.a = 100; // window } } obj.b(); console.log(obj.a,a);
7.arr(陣列新方法)
filter過濾 forEach 迴圈 map 對映 reduce 收斂 some every 反義
7.1 reduce(收斂)
原生寫法
let arr = [1,2,3,4,5]; Array.prototype.myReduce = function (callback,prev) { for(let i = 0 ; i<this.length;i++){ if(!prev){ // 0 1 prev = callback(this[i],this[i+1],i+1,this); i++; }else{ prev = callback(prev,this[i],i+1,this); } } return prev } let r = arr.myReduce((prev,next,currentIndex,arr)=>{ return prev+next },100)
7.2 filter(過濾)
let arr = [1,2,3] let arr1 = arr.filter(item=>item<=2); console.log(arr1);
7.3 map
let arr =[1,2,3]; let arr1 = arr.map(item=>item*2);
7.3 every
let arr = [1,2,3]; let flag = arr.every(item=>item==3); console.log(arr.includes(3)); //es7
7.4 findIndex
let arr = [1, 2, 3]; let item = arr.find(item => item == 4); console.log(item); //es7
7.5 Array.from
將一個數組或者類陣列變成陣列,會複製一份
let newArr = Array.from(oldArr);
7.6 Array.of()
of是為了將一組數值,轉換為陣列
console.log(Array(3), Array(3).length); console.log(Array.of(3), Array.of(3).length);
7.7 copyWithin
Array.prototype.copyWithin(target, start = 0, end = this.length) 覆蓋目標的下標 開始的下標 結束的後一個的下標
[1, 2, 3, 4, 5].copyWithin(0, 1, 2)//[ 2, 2, 3, 4, 5 ]
7.8 Object.keys
Object.keys可以把物件取出來key組成陣列 for of 可以迭代陣列
for (var a of Object.values({ name: 'cjw', age: 9 }) ){ // forEach不能return console.log(a); }
8.Symbol
let s = Symbol(); let q = Symbol(); console.log(s === q);//false let s = Symbol.for('cjw'); let q = Symbol.for('cjw'); console.log(s);//Symbol(cjw) console.log(q);//Symbol(cjw) console.log(Symbol.keyFor(q)); console.log(s === q);//ture
9.template
9.1 模板字串
let name = 'cjw'; let age = 9; let str = `${name}今年${age}`; console.log(str);
9.2 模板字串實現原理
let newStr = str.replace(/\$\{([\s\S])\}/g, function(){ return eval(arguments); }) console.log(newStr);
10.集合
10.1 Set
set可以做去重 set不能放重複的
let set = new Set([1,2,3,3,2,1]); console.log([...set]);
10.2 Map
let map = new Map(); map.set('js','123'); map.set('node','456'); map.forEach(item=>{ console.log(item); });
11 class
11.1 es5 實現的類
// call 建構函式裡面的屬性方法複製
// Object.crate 複製原型裡面的屬性和方法
function Animal(type) { this.type = { t: type}; } Animal.prototype.eat = function () { console.log('eat'); } function Cat(type) { Animal.call(this,type); // 讓父類在子類中執行,並且this指向子類 } // 原型上還有一個屬性 // 4.繼承例項上和原型上的方法 function create(proto) { let Fn = function () { } Fn.prototype = proto; return new Fn(); } Cat.prototype = Object.create(Animal.prototype,{constructor:{value:Cat}}); let cat = new Cat('哺乳類') console.log(cat.type); cat.eat(); console.log(cat.constructor);
11.2 es6 寫法
class Animal { constructor(type){ this.type = type; } static flag(){ return 'animal'; } eat(){ console.log('eat'); } } class Cat extends Animal{ constructor(type){ super(type); } } let cat = new Cat('哺乳類'); console.log(cat.type); cat.eat(); console.log(Cat.flag);
11.3 get 與 set
getter可以用來得獲取屬性,setter可以去設定屬性
class Person { constructor(){ this.hobbies = []; } set hobby(hobby){ this.hobbies.push(hobby); } get hobby(){ return this.hobbies; } } let person = new Person(); person.hobby = 'basketball'; person.hobby = 'football'; console.log(person.hobby);
參考文件
ofollow,noindex" target="_blank">ECMAScript 6 入門 let 和 const 命令--阮一峰