1 對象的方法補充
2 原型繼承關(guān)系圖
3 class方式定義類
4 extends實現(xiàn)繼承
5 extends實現(xiàn)繼承
6 多態(tài)概念的理
function 創(chuàng)建的名稱如果開頭是大寫的,那這個創(chuàng)建的不是函數(shù),是創(chuàng)建了類。
?ES6-class類中的內(nèi)容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var obj = { running: function() {}, eating: () => {}, swimming() { } } // function Person() { // } // Person.prototype.running = function() { // } // 編程: 高內(nèi)聚低耦合 class Person { // 1.類中的構(gòu)造函數(shù) // 當(dāng)我們通過new關(guān)鍵字調(diào)用一個Person類時, 默認(rèn)調(diào)用class中的constructor方法 constructor(name, age) { this.name = name this.age = age } // 2.實例方法 // 本質(zhì)上是放在Person.prototype running() { console.log(this.name + " running~") } eating() { console.log(this.name + " eating~") } } // 創(chuàng)建實例對象 var p1 = new Person("why", 18) // 使用實例對象中屬性和方法 console.log(p1.name, p1.age) p1.running() p1.eating() // 研究內(nèi)容 console.log(Person.prototype === p1.__proto__) console.log(Person.running) // 不能調(diào)用 console.log(Person.prototype.running) // 可以調(diào)用 </script> </body> </html>
ES6-class和function類的區(qū)別
可以把class創(chuàng)建的類當(dāng)做是function創(chuàng)建的類的一種語法糖。但是在直接使用的方面是有不同之處。類里面的方法又叫靜態(tài)方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // function定義類 function Person1(name, age) { this.name = name this.age = age } Person1.prototype.running = function() {} Person1.prototype.eating = function() {} var p1 = new Person1("why", 18) console.log(p1.__proto__ === Person1.prototype) console.log(Person1.prototype.constructor) console.log(typeof Person1) // function // 不同點: 作為普通函數(shù)去調(diào)用 Person1("abc", 100) // class定義類 class Person2 { constructor(name, age) { this.name = name this.age = age } running() {} eating() {} } var p2 = new Person2("kobe", 30) console.log(p2.__proto__ === Person2.prototype) console.log(Person2.prototype.constructor) console.log(typeof Person2) // 不同點: class定義的類, 不能作為一個普通的函數(shù)進(jìn)行調(diào)用 Person2("cba", 0) </script> </body> </html>
ES6-對象訪問器方法的編寫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 針對對象 // 方式一: 描述符 // var obj = { // _name: "why" // } // Object.defineProperty(obj, "name", { // configurable: true, // enumerable: true, // set: function() { // }, // get: function() { // } // }) // 方式二: 直接在對象定義訪問器 // 監(jiān)聽_name什么時候被訪問, 什么設(shè)置新的值 var obj = { _name: "why", // setter方法 set name(value) { this._name = value }, // getter方法 get name() { return this._name } } obj.name = "kobe" console.log(obj.name) </script> </body> </html>
ES6-類的訪問器方法的編寫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 1.訪問器的編寫方式 // class Person { // // 程序員之間的約定: 以_開頭的屬性和方法, 是不在外界訪問 // constructor(name, age) { // this._name = name // } // set name(value) { // console.log("設(shè)置name") // this._name = value // } // get name() { // console.log("獲取name") // return this._name // } // } // var p1 = new Person("why", 18) // p1.name = "kobe" // console.log(p1.name) // // console.log(p1._name) // var p2 = new Person("james", 25) // console.log(p2.name) // 2.訪問器的應(yīng)用場景 class Rectangle { constructor(x, y, width, height) { this.x = x this.y = y this.width = width this.height = height } get position() { return { x: this.x, y: this.y } } get size() { return { width: this.width, height: this.height } } } var rect1 = new Rectangle(10, 20, 100, 200) console.log(rect1.position) console.log(rect1.size) </script> </body> </html>
ES6-類的靜態(tài)方法的編寫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // function Person() {} // // 實例方法 // Person.prototype.running = function() {} // // 類方法 // Person.randomPerson = function() {} // var p1 = new Person() // p1.running() // Person.randomPerson() // class定義的類 var names = ["abc", "cba", "nba", "mba"] class Person { constructor(name, age) { this.name = name this.age = age } // 實例方法 running() { console.log(this.name + " running~") } eating() {} // 類方法(靜態(tài)方法) static randomPerson() { console.log(this) var randomName = names[Math.floor(Math.random() * names.length)] return new this(randomName, Math.floor(Math.random() * 100)) } } var p1 = new Person() p1.running() p1.eating() var randomPerson = Person.randomPerson() console.log(randomPerson) </script> </body> </html>
ES6-通過extends實現(xiàn)繼承
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 定義父類 class Person { constructor(name, age) { this.name = name this.age = age } running() { console.log("running~") } eating() { console.log("eating~") } } class Student extends Person { constructor(name, age, sno, score) { // this.name = name // this.age = age super(name, age) this.sno = sno this.score = score } // running() { // console.log("running~") // } // eating() { // console.log("eating~") // } studying() { console.log("studying~") } } var stu1 = new Student("why", 18, 111, 100) stu1.running() stu1.eating() stu1.studying() class Teacher extends Person { constructor(name, age, title) { // this.name = name // this.age = age super(name, age) this.title = title } // running() { // console.log("running~") // } // eating() { // console.log("eating~") // } teaching() { console.log("teaching~") } } </script> </body> </html>
ES6-super關(guān)鍵字的其他用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> class Animal { running() { console.log("running") } eating() { console.log("eating") } static sleep() { console.log("static animal sleep") } } class Dog extends Animal { // 子類如果對于父類的方法實現(xiàn)不滿足(繼承過來的方法) // 重新實現(xiàn)稱之為重寫(父類方法的重寫) running() { console.log("dog四條腿") // 調(diào)用父類的方法 super.running() // console.log("running~") // console.log("dog四條腿running~") } static sleep() { console.log("趴著") super.sleep() } } var dog = new Dog() dog.running() dog.eating() Dog.sleep() </script> </body> </html>
繼承自內(nèi)置類的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 1.創(chuàng)建一個新的類, 繼承自Array進(jìn)行擴(kuò)展 class HYArray extends Array { get lastItem() { return this[this.length - 1] } get firstItem() { return this[0] } } var arr = new HYArray(10, 20, 30) console.log(arr) console.log(arr.length) console.log(arr[0]) console.log(arr.lastItem) console.log(arr.firstItem) // 2.直接對Array進(jìn)行擴(kuò)展 Array.prototype.lastItem = function() { return this[this.length - 1] } var arr = new Array(10, 20, 30) console.log(arr.__proto__ === Array.prototype) console.log(arr.lastItem()) // 函數(shù)apply/call/bind方法 -> Function.prototype </script> </body> </html>
ES6-類的混入mixin的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // JavaScript只支持單繼承(不支持多繼承) function mixinAnimal(BaseClass) { return class extends BaseClass { running() { console.log("running~") } } } function mixinRunner(BaseClass) { return class extends BaseClass { flying() { console.log("flying~") } } } class Bird { eating() { console.log("eating~") } } // var NewBird = mixinRunner(mixinAnimal(Bird)) class NewBird extends mixinRunner(mixinAnimal(Bird)) { } var bird = new NewBird() bird.flying() bird.running() bird.eating() </script> </body> </html>
ES6-ES6中的class轉(zhuǎn)ES5代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // class Person { // constructor(name, age) { // this.name = name // this.age = age // } // running() {} // eating() {} // static randomPerson() {} // } // var p1 = new Person() </script> <script src="./js/es5_code01.js"></script> </body> </html>
可以去babel官網(wǎng)打開try out,然后改default。
ES6-Java面向?qū)ο蟮亩鄳B(tài)理解
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 繼承是多態(tài)的前提 // shape形狀 class Shape { getArea() {} } class Rectangle extends Shape { constructor(width, height) { super() this.width = width this.height = height } getArea() { return this.width * this.height } } class Circle extends Shape { constructor(radius) { super() this.radius = radius } getArea() { return this.radius * this.radius * 3.14 } } var rect1 = new Rectangle(100, 200) var rect2 = new Rectangle(20, 30) var c1 = new Circle(10) var c2 = new Circle(15) // 表現(xiàn)形式就是多態(tài) /* 在嚴(yán)格意義的面向?qū)ο笳Z言中, 多態(tài)的是存在如下條件的: 1.必須有繼承(實現(xiàn)接口) 2.必須有父類引用指向子類對象 */ function getShapeArea(shape) { console.log(shape.getArea()) } getShapeArea(rect1) getShapeArea(c1) var obj = { getArea: function() { return 10000 } } getShapeArea(obj) getShapeArea(123) </script> </body> </html>
ES6-JS面向?qū)ο蟮亩鄳B(tài)理解
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 多態(tài)的表現(xiàn): JS到處都是多態(tài) function sum(a1, a2) { return a1 + a2 } sum(20, 30) sum("abc", "cba") // 多態(tài)的表現(xiàn) var foo = 123 foo = "Hello World" console.log(foo.split()) foo = { running: function() {} } foo.running() foo = [] console.log(foo.length) </script> </body> </html>
ES6-對象字面量的增強寫法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> /* 1.屬性的增強 2.方法的增強 3.計算屬性名的寫法 */ var name = "why" var age = 18 var key = "address" + " city" var obj = { // 1.屬性的增強 name, age, // 2.方法的增強 running: function() { console.log(this) }, swimming() { console.log(this) }, eating: () => { console.log(this) }, // 3.計算屬性名 [key]: "廣州" } obj.running() obj.swimming() obj.eating() function foo() { var message = "Hello World" var info = "my name is why" return { message, info } } var result = foo() console.log(result.message, result.info) </script> </body> </html>
ES6-數(shù)組和對象的解構(gòu)語法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var names = ["abc", "cba", undefined, "nba", "mba"] // 1.數(shù)組的解構(gòu) // var name1 = names[0] // var name2 = names[1] // var name3 = names[2] // 1.1. 基本使用 // var [name1, name2, name3] = names // console.log(name1, name2, name3) // 1.2. 順序問題: 嚴(yán)格的順序 // var [name1, , name3] = names // console.log(name1, name3) // 1.3. 解構(gòu)出數(shù)組 // var [name1, name2, ...newNames] = names // console.log(name1, name2, newNames) // 1.4. 解構(gòu)的默認(rèn)值 var [name1, name2, name3 = "default"] = names console.log(name1, name2, name3) // 2.對象的解構(gòu) var obj = { name: "why", age: 18, height: 1.88 } // var name = obj.name // var age = obj.age // var height = obj.height // 2.1. 基本使用 // var { name, age, height } = obj // console.log(name, age, height) // 2.2. 順序問題: 對象的解構(gòu)是沒有順序, 根據(jù)key解構(gòu) // var { height, name, age } = obj // console.log(name, age, height) // 2.3. 對變量進(jìn)行重命名 // var { height: wHeight, name: wName, age: wAge } = obj // console.log(wName, wAge, wHeight) // 2.4. 默認(rèn)值 var { height: wHeight, name: wName, age: wAge, address: wAddress = "中國" } = obj console.log(wName, wAge, wHeight, wAddress) // 2.5. 對象的剩余內(nèi)容 var { name, age, ...newObj } = obj console.log(newObj) // 應(yīng)用: 在函數(shù)中(其他類似的地方) // function getPosition(position)直接把position解構(gòu)成{ x, y },方便拿對象里面的參數(shù) function getPosition({ x, y }) { console.log(x, y) } getPosition({ x: 10, y: 20 }) getPosition({ x: 25, y: 35 }) function foo(num) {} foo(123) </script> </body> </html>
補充-手寫apply-call函數(shù)實現(xiàn)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // new Function() // foo.__proto__ === Function.prototype function foo(name, age) { console.log(this, name, age) } // foo函數(shù)可以通過apply/call // foo.apply("aaa", ["why", 18]) // foo.call("bbb", "kobe", 30) // 1.給函數(shù)對象添加方法: hyapply Function.prototype.hyapply = function(thisArg, otherArgs) { // this -> 調(diào)用的函數(shù)對象 // thisArg -> 傳入的第一個參數(shù), 要綁定的this // console.log(this) // -> 當(dāng)前調(diào)用的函數(shù)對象 // this.apply(thisArg) thisArg.fn = this // 1.獲取thisArg, 并且確保是一個對象類型 thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg) // thisArg.fn = this Object.defineProperty(thisArg, "fn", { enumerable: false, configurable: true, value: this }) thisArg.fn(...otherArgs) delete thisArg.fn } // foo.hyapply({ name: "why" }, ["james", 25]) // foo.hyapply(123, ["why", 18]) // foo.hyapply(null, ["kobe", 30]) // 2.給函數(shù)對象添加方法: hycall Function.prototype.hycall = function(thisArg, ...otherArgs) { // 1.獲取thisArg, 并且確保是一個對象類型 thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg) // thisArg.fn = this Object.defineProperty(thisArg, "fn", { enumerable: false, configurable: true, value: this }) thisArg.fn(...otherArgs) delete thisArg.fn } foo.hycall({ name: "why", fn: "abc" }, "james", 25) foo.hycall(123, "why", 18) foo.hycall(null, "kobe", 30) </script> </body> </html>
補充-手寫apply-call抽取封裝
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // new Function() // foo.__proto__ === Function.prototype function foo(name, age) { console.log(this, name, age) } // foo函數(shù)可以通過apply/call // foo.apply("aaa", ["why", 18]) // foo.call("bbb", "kobe", 30) // 1.封裝思想 // 1.1.封裝到獨立的函數(shù)中 function execFn(thisArg, otherArgs, fn) { // 1.獲取thisArg, 并且確保是一個對象類型 thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg) // thisArg.fn = this Object.defineProperty(thisArg, "fn", { enumerable: false, configurable: true, value: fn }) // 執(zhí)行代碼 thisArg.fn(...otherArgs) delete thisArg.fn } // 1.2. 封裝原型中 Function.prototype.hyexec = function(thisArg, otherArgs) { // 1.獲取thisArg, 并且確保是一個對象類型 thisArg = (thisArg === null || thisArg === undefined)? window: Object(thisArg) // thisArg.fn = this Object.defineProperty(thisArg, "fn", { enumerable: false, configurable: true, value: this }) thisArg.fn(...otherArgs) delete thisArg.fn } // 1.給函數(shù)對象添加方法: hyapply Function.prototype.hyapply = function(thisArg, otherArgs) { this.hyexec(thisArg, otherArgs) } // 2.給函數(shù)對象添加方法: hycall Function.prototype.hycall = function(thisArg, ...otherArgs) { this.hyexec(thisArg, otherArgs) } foo.hyapply({ name: "why" }, ["james", 25]) foo.hyapply(123, ["why", 18]) foo.hyapply(null, ["kobe", 30]) foo.hycall({ name: "why" }, "james", 25) foo.hycall(123, "why", 18) foo.hycall(null, "kobe", 30) </script> </body> </html>
補充-手寫bind函數(shù)的實現(xiàn)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // apply/call function foo(name, age, height, address) { console.log(this, name, age, height, address) } // Function.prototype // var newFoo = foo.bind({ name: "why" }, "why", 18) // newFoo(1.88) // 實現(xiàn)hybind函數(shù) Function.prototype.hybind = function(thisArg, ...otherArgs) { // console.log(this) // -> foo函數(shù)對象 thisArg = thisArg === null || thisArg === undefined ? window: Object(thisArg) Object.defineProperty(thisArg, "fn", { enumerable: false, configurable: true, writable: false, value: this }) return (...newArgs) => { // var allArgs = otherArgs.concat(newArgs) var allArgs = [...otherArgs, ...newArgs] thisArg.fn(...allArgs) } } var newFoo = foo.hybind("abc", "kobe", 30) newFoo(1.88, "廣州市") newFoo(1.88, "廣州市") newFoo(1.88, "廣州市") newFoo(1.88, "廣州市") </script> </body> </html>
文章來源:http://www.zghlxwxcb.cn/news/detail-574131.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-574131.html
到了這里,關(guān)于JavaScript ES6實現(xiàn)繼承的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!