第5章 JS基礎-原型和原型鏈【三座大山之一,必考!!!】

返回章節目錄

 

目錄

1.class和繼承

class

繼承

類型判斷-instanceof

2.原型

原型關係

基於原型的執行規則

3.原型鏈和instanceof

原型鏈

再看instanceof

4.練習題

1.如何判斷準確判斷一個變量是不是數組?

2.class方法的本質?

3.手寫簡易jQuery考慮插件和擴展性


 

1.class和繼承

class

關於class的代碼如下,看起來還是蠻像java代碼的

// 類
class Student {
    constructor(name, number) {
        this.name = name // 這個對象裏新增一個name賦值爲傳進來的name
        this.number = number
        // this.gender = 'male'
    }
    sayHi() {
        console.log(
            `姓名 ${this.name} ,學號 ${this.number}`
        )
        // console.log(
        //     '姓名 ' + this.name + ' ,學號 ' + this.number
        // )
    }
    // study() {

    // }
}

// 通過類 new 對象/實例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()

const madongmei = new Student('馬冬梅', 101)
console.log(madongmei.name)
console.log(madongmei.number)
madongmei.sayHi()

運行結果

 

繼承

代碼如下,還是和java很像,主要看一下js中該怎麼用,記住這個例子,後面所有的講解圍繞這段代碼展開

// 父類
class People {
    constructor(name) {
        this.name = name
    }
    eat() {
        console.log(`${this.name} eat something`)
    }
}

// 子類
class Student extends People {
    constructor(name, number) {
        super(name)
        this.number = number
    }
    sayHi() {
        console.log(`姓名 ${this.name} 學號 ${this.number}`)
    }
}

// 子類
class Teacher extends People {
    constructor(name, major) {
        super(name)
        this.major = major
    }
    teach() {
        console.log(`${this.name} 教授 ${this.major}`)
    }
}

// 實例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
xialuo.eat()

// 實例
const wanglaoshi = new Teacher('王老師', '語文')
console.log(wanglaoshi.name)
console.log(wanglaoshi.major)
wanglaoshi.teach()
wanglaoshi.eat()

運行結果:

經過我的測試,發現如果沒有構造器constructor,默認的賦值就不行,也不會和java一樣默認構造器,也不會默認調用super,不會報錯,相關變量只會undefined

 

類型判斷-instanceof

還是接着上面的繼承的例子來看

注意細節:剛剛在Student中定義的方法sayHi(),結果在Student的原型Student.prototype中

有小夥伴已經摸索出來了,到底instanceof是怎麼樣的呢?我們看看原型再來說明instanceof

 

2.原型

控制檯看一下

Student.prototype和xialuo.__pro__的關係如下

剛剛在Student中定義的方法sayHi(),結果在Student的原型Student.prototype中,所以可以說明在class中定義的方法是在這個class的prototype中的,是所有實例共同擁有的。

 

 

原型關係

每個class都有顯式原型prototype

每個實例都有隱式原型__proto__

實例的__proto__指向對應class的prototype

 

基於原型的執行規則

獲取屬性xialuo.name或執行方法xialuo.sayHi()時,先在自身屬性和方法尋找,如果找不到則自動去__pro__中查找

 

3.原型鏈和instanceof

運行結果如下

原型鏈

xialuo是new Student出來的,是一個Student對象,xialuo的__proto__等於Student的Prototype

這裏People.prototype和Student.prototype.__proto__是相等的,也可以認爲Student.prototype是new出來People對象

People.prototype.__proto__和Object.prototype是相等的,那麼可以認爲People.prototype是new出來的Object對象

Student.prototype instanceof People 爲true

People.prototype instanceof Object 也爲true

這個關係真的好奇妙啊

我是你new出來的,我的隱式__pro__等於你的顯式prototype

反過來也是,我的隱式__pro__等於你的顯式prototype,那麼我就是你new出來的對象

 

再看instanceof

直接總結:A instanceof B成立的條件爲

左邊A的隱式__proto__鏈上能找到一個等於右邊B的顯式prototype則爲true,否則爲false

 

提示:

 

4.練習題

1.如何判斷準確判斷一個變量是不是數組?

A instanceof Array

 

2.class方法的本質?

        在class Student中定義的方法sayHi(),結果在Student的原型Student.prototype中,所以可以說明在class中定義的方法是在這個class的prototype中的,這樣才能實現new出來的實例都有這個方法

       獲取屬性或執行方法時,先在自身屬性和方法尋找,如果找不到則自動去__pro__中查找

 

3.手寫簡易jQuery考慮插件和擴展性

更方便理解class和原型

class jQuery {
    constructor(selector) {
        const result = document.querySelectorAll(selector) // 返回NodeList
        const length = result.length
        for (let i = 0; i < length; i++) {
            this[i] = result[i]
        }
        this.length = length
        this.selector = selector
    }
    get(index) {
        return this[index]
    }
    each(fn) {
        for (let i = 0; i < this.length; i++) {
            const elem = this[i]
            fn(elem)
        }
    }
    on(type, fn) {
        return this.each(elem => {
            elem.addEventListener(type, fn, false)
        })
    }
    // 擴展很多 DOM API
}

// 插件
jQuery.prototype.dialog = function (info) {
    alert(info)
}

// “造輪子”
class myJQuery extends jQuery {
    constructor(selector) {
        super(selector)
    }
    // 擴展自己的方法
    addClass(className) {

    }
    style(data) {
        
    }
}

// const $p = new jQuery('p')
// $p.get(1)
// $p.each((elem) => console.log(elem.nodeName))
// $p.on('click', () => alert('clicked'))

測試代碼:

index.js

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>js 基礎知識 演示</title>
    </head>
    <body>
        <p>一段文字 1</p>
        <p>一段文字 2</p>
        <p>一段文字 3</p>

        <script src="./jquery-demo.js"></script>
    </body> 
</html>

我們來看看再控制檯的運行顯示

 

點擊p元素後顯示如下

然後再添加on監聽事件

鼠標移動到p則顯示

 

關注、留言,我們一起學習。

 

===============Talk is cheap, show me the code================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章