ES6中,class , iterator,generator ,物件的擴充套件,嚴格模式,陣列的擴充套件,遞迴實現深拷貝
一、class
語法:class是建構函式的語法糖
class Cat { constructor(name) { // 本身方法 this.name = name; }; run() { // 原型方法 console.log(this.name + "running") }; }; let cat1 = new Cat("小花"); console.log(cat1);
- 注意不需要return,如果是基本型別值不會輸出,如果是引用型別改變;
- constructor和 方法都是在原型上面;
- 瞭解:class 有一個getter函式和setter函式:
class Cat { get name() { return "小黑"; }; set name(val) { console.log(val); }; }; let cat1= new Cat(); console.log(cat1); cat1.name = "hello";
注: 不使用constructor可以省略不寫;
靜態和例項(成員):
例項方法和例項屬性(成員方法和屬性)必須通過用例項化進行呼叫;
靜態屬性和方法:通過類進行呼叫;
1.繼承:
1)語法: extends關鍵字
class Parent { constructor(name) { this.name = name; }; fn() { console.log("fn"); }; };
classchildrenextendsParent{
// 預設省略可以省略constructor
constructor(x,color){
super(x) ; //呼叫父類的constructor方法
this.color=color;
};
};
letc1=newchildren("小花");
console.log(c1);
c1.fn();
2)手動在子類新增constructor,必須在construtor寫super();
3)Super 方法和屬性:
Super方法:呼叫父類的constructor方法;
Super屬性:在子類裡面,呼叫父類的屬性和方法;
二、iterator:
- 概念:在集合的資料結構中,陣列,物件,set,map 需要統一介面,來進行處理。Iterator就是這個機制,為不同的資料結構提供統一的介面,任何的資料結構,只要部署了iterator就可以進行迴圈遍歷。
- 作用:1.提供統一介面,2.按照一定的順序迴圈遍歷,3.為for...of...提供消費
- 目的:提供統一介面
- 模擬iterator介面:
let arr = ["a", "b", "c"]; function myIterator(arr) { let index = 0; return { next() { // if (index < arr.length) { // return { // value: arr[index++], // done: false // } // } else { // return { // value: undefined, // done: true // } // }; return index < arr.length ? { value: arr[index++], done: false } : { value: undefined, done: true }; }; }; }; let x = myIterator(arr); console.log(x.next()); // {value: "a", done: false} console.log(x.next()); // {value: "b", done: false} console.log(x.next()); // {value: "c", done: false} console.log(x.next()) ; // {value: undifined, done: true}
1.建立的是一個指標物件,指向當前資料結構的起始位置
2.第一次呼叫next指向的是第一個位置的元素
3.第二次呼叫next指向的是第二個位置的元素
4.一直指向到結束位置;
注意:done為false表示可以繼續迴圈遍歷,done為true表示迴圈遍歷結束;
5.預設的 Iterator 介面部署在資料結構的Symbol.iterator屬性;
obj[Symbol.iterator] = function() { let index = 0; return { next: () => { // console.log(Object.keys(this).length) // console.log(Object.keys(this)[index]) // 取屬性 // console.log(this) //物件 // console.log(this[Object.keys(this)[index]]) // 取值 if (index < Object.keys(this).length) { return { value: this[Object.keys(this)[index++]], done: false } } else { return { value: undefined, done: true } } } } }
三、Generator
1.概念:
解決非同步程式設計方法;
是一個狀態機,可以從函式的內部返回多個狀態
返回的是一個iterator物件
2.語法
1)在function和函式名中間寫一個*
2)返回的是一個iterator物件,通過呼叫next()來獲取值
3)通過yield可以在函式的外部返回多個狀態,狀態機
4)因為返回的是一個iterator物件,所以可以使用for...of...
5)注意:可以使用return,但是return返回done:true;表示迴圈遍歷已經結束;
for...of...迴圈是拿不到return後面的值;
6)Yield有阻塞程式碼執行,必須呼叫next方法之後,才可以執行;
function * fn(){ console.log(fn()); let aa = 8; console.log(aa); yield 'hello'; yield 2 + 1; let a = yield 4; // let b; console.log(a); let b = yield 12; return b; } let g = fn(); console.log(g.next()); // fn{<suspended>} 8 {value: "hello", done: false} console.log(g.next()); // {value: 3, done: false} console.log(g.next()); // {value: 4, done: false} console.log(g.next(9)); // 9 {value: 12, done: false} console.log(g.next(10)); // {value: 10, done: true}
四、擴充套件內容:
1. 物件的擴充套件
let obj = { a: 1, b: 2 }; console.log(Object.getOwnPropertyDescriptor(obj, "a")); // {value: 1, writable: true, enumerable: true, configurable: true} Object.defineProperty(obj,'a',{ // value: 'hello', writable : false, // 是否可修改值 enumerable: false, //是否可遍歷 configurable: false // 是否可設定 }); obj.a = 'www'; console.log(obj.a); // 1 for(let key in obj){ console.log(key); // b }; console.log(Object.values(obj)); // [2]
2. 嚴格模式:
注意:"use strict"; 必須放在js檔案的第一行或者是函式的第一行;
2.1 變數必須先宣告,再使用
2.2 This不允許指向全域性物件,返回的是undefined
2.3 關於arguments
2.4 對於只讀屬性,不能夠重新賦值
<script>
'use strict' // this不允許指向全域性物件 function fn1(){ console.log(this); }; fn1(); // undifined // 不允許arguments重新賦值 function fn2(){ console.log(arguments); // Arguments(4)[1, 2, 3, 4, callee: (...), Symbol(Symbol.iterator): ƒ] console.log(Array.prototype.slice.call(arguments)); // (4)[1, 2, 3, 4] // arguments = 'hello'; // console.log(arguments); //會報錯 } fn2(1,2,3,4); // 不再追蹤引數的變化 function fn3(num){ num++; console.log(arguments); // Arguments(3)[2, 3, 4, callee: (...), Symbol(Symbol.iterator): ƒ] }; fn3(2,3,4); // 不允許使用callee function fn4(){ console.log(arguments.callee);// 獲取的是函式本身 }; // fn4(); // 不允許修改物件的只讀屬性,否則會報錯 let obj = { a : 10 }; Object.defineProperty(obj,'a',{ // writable: false, configurable: false, enumerable: false }); obj.a = 'hello'; console.log(obj); // {a: "hello"} </script>
3. 陣列擴充套件:
Array.of() 將一組值轉為一個數組,彌補Array建構函式的不足
find() 返回第一個符合條件的元素;
findIndex() 返回第一個符合條件的元素的下標
Includes() 不僅可以在陣列中使用,也可以在字串中使用;判斷一個元素是否存在,返回的是一個布林值;
<script> let arr = new Array(5); console.log(arr); //(5)[empty × 5] let arr1 = [5]; console.log(arr1); //[5] let arr2 = Array.of(12, 24, 34); console.log(arr2); // (3)[12, 24, 34] let arr3 = [1, 2, 3, 4, 5, 6, 7]; let x = arr3.find((item, index, array) => { // console.log(item,index,array); return item > 3; }); console.log(x); // 4 let x2 = arr3.findIndex(item => item > 3); console.log(x2); // 3 console.log(arr3.includes('hello')); //false console.log(arr3.includes(4)); // true let str = 'hello'; console.log(str.includes('hello')); // true console.log(str.includes('he')); // true </script>
深拷貝:
遞迴實現深拷貝:
let obj = { a: 1, b: 'hello', c: undefined, arr: [12, 34], ob: { ha: 'haha' }, fn: function () { console.log('fn'); } }; let copy = JSON.parse(JSON.stringify(obj)); // 不能拷貝undefined和函式 console.log(copy); // 遞迴實現深拷貝 function deepCopy(obj, newObj = {}) { for (let key in obj) { if (typeof obj[key] === 'object') { newObj[key] = Array.isArray(obj[key]) ? [] : {}; deepCopy(obj[key], newObj[key]); } else { newObj[key] = obj[key]; }; }; return newObj; }; let dc = deepCopy(obj); dc.arr[0] = 3; console.log(dc, obj);