国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS核心知識(shí)點(diǎn)梳理——原型、繼承(下)

joyqi / 1591人閱讀

摘要:引言上篇文章介紹原型,這篇文章接著講繼承,嘔心瀝血之作,大哥們點(diǎn)個(gè)贊呀明確一點(diǎn)并不是真正的面向?qū)ο笳Z(yǔ)言,沒(méi)有真正的類,所以我們也沒(méi)有類繼承實(shí)現(xiàn)繼承有且僅有兩種方式,和原型鏈在介紹繼承前我們先介紹下其他概念函數(shù)的三種角色一個(gè)函數(shù),有三種角色。

引言

上篇文章介紹原型,這篇文章接著講繼承,嘔心瀝血之作,大哥們點(diǎn)個(gè)贊呀

明確一點(diǎn):JavaScript并不是真正的面向?qū)ο笳Z(yǔ)言,沒(méi)有真正的類,所以我們也沒(méi)有類繼承

實(shí)現(xiàn)繼承==有且僅有兩種方式,call和原型鏈==

在介紹繼承前我們先介紹下其他概念

函數(shù)的三種角色

一個(gè)函數(shù),有三種角色。
當(dāng)成普通函數(shù),當(dāng)成構(gòu)造函數(shù)(類),當(dāng)成對(duì)象

function Person (nickname) {
        var age = 15 //當(dāng)普通函數(shù)使 **重點(diǎn):稱為私有屬性**
        this.age = 30    //當(dāng)構(gòu)造函數(shù)使 **重點(diǎn):稱為實(shí)例屬性**
    }
    Person.prototype.age = 50 //當(dāng)構(gòu)造函數(shù)使   **重點(diǎn):稱為原型屬性**
    Person.age =100  //當(dāng)對(duì)象使 **重點(diǎn):稱為靜態(tài)屬性**    

==我個(gè)人把屬性和方法統(tǒng)一稱為廣義上的屬性,所以上面說(shuō)法其實(shí)不嚴(yán)謹(jǐn)==

大家猜一猜Array.isArray是靜態(tài)方法還是原型方法,為啥?Array.push呢?

繼承的方式

繼承原則:
使用call繼承實(shí)例上的屬性
使用原型鏈繼承原型上的屬性
子類需要有自己的原型,父類也必須要有自己的原型,子實(shí)例在自己的原型上找不到屬性的時(shí)候才會(huì)到父原型上去找(這也就是子類.prototype = 父類.prototype不行的原因,因?yàn)樗鼈冎虚g沒(méi)有==“緩沖”==,改了子類原型相當(dāng)于就改了父類原型!)

組合繼承
const Person = function (name) {
        this.name = name
    }
Person.prototype.introduce = function(){
  Object.entries(this).forEach((item)=>{
        console.log(`my ${item[0]} is ${item[1]}`)
    })
    
}

const Student = function (name,age) {
        Person.call(this,name)
        this.age = age
    }
Student.prototype = new Person()      //這里new了父類一次,增加了額外開(kāi)銷
Student.prototype.constructor =  Student         //這一句可以讓student.constructor.name由Person變?yōu)镾tudent 方便確認(rèn)構(gòu)造函數(shù)

let student = new Student("小明",15)
student.introduce()  繼承父類原型方法的同時(shí)繼承父類實(shí)例上的屬性
//my name is 小明
//my age is 15      

組合繼承有一個(gè)缺點(diǎn),會(huì)額外new父類一次,增加了額外開(kāi)銷(想一想如果父類特別大這消耗會(huì)有多大)

Object.create繼承(原型式繼承)

從名字也看出來(lái)了,借用原型鏈繼承,實(shí)例能通過(guò)__proto__追蹤到傳入到參數(shù)obj,所以源碼如下
//Oject.create(obj)
Object.create = function(obj){

var fn = funcion(){}
fn.prototype = obj
reurturn new fn() 

}
var A = Object.create(B) //A能找到B
=再次強(qiáng)調(diào)一遍,A通過(guò)原型鏈最終到B=

優(yōu)化組合繼承==>寄生組合式繼承

我們?cè)倏匆幌陆M合繼承的原型鏈 Student-->Person的實(shí)例-->Person
還記得我們?cè)谧铋_(kāi)始繼承原則中說(shuō)的緩沖嗎,Person的實(shí)例就是這么一個(gè)緩沖 但是缺點(diǎn)就是構(gòu)造這么一個(gè)緩沖開(kāi)銷大了

所以我們有一個(gè)優(yōu)化手段

Student.prototype = new Person()  //未優(yōu)化的時(shí)候   Person實(shí)例充當(dāng)原型鏈的中間對(duì)象(緩沖)
-------------------------
Student.prototype = Object.create(Person.prototype) //優(yōu)化后    一個(gè)繼承Person的空對(duì)象充當(dāng)中間對(duì)象(緩沖)
------------------------
Student.prototype.__proto__ = Person.prototype  //當(dāng)然也有人這么寫  道理都是一樣,Student.prototype.__proto__做緩沖
new干了啥

既然new在“類”的創(chuàng)建里面必須使用,那么我們就說(shuō)一下new到底干了啥事情

1.創(chuàng)建一個(gè)對(duì)象o繼承構(gòu)造函數(shù)
2.讓構(gòu)造函數(shù)的this變?yōu)閛,并執(zhí)行構(gòu)造函數(shù),將返回值設(shè)置為k
3.如果k

//仿寫new
function new1(func) {
        var o = Object.create(func.prototype)
        var k = func.apply(o,arguments[1])
        return typeof k === "object"? k: o
    }
const x = new1(Student,["張三"])
x.name //"張三"
x.eat //"i am hungry,i want to eat!"

我們回過(guò)頭再分析一下構(gòu)造函數(shù)模式繼承

const Person = function (name) {
        this.name = name
    }
const Students = function (name) {
        Person.call(this,name) //this是student實(shí)例
    }
const xm = new Students("小明")  //分析這里干了什么
console.log(xm)  //Students?{name: "小明"}

1.讓空對(duì)象o繼承Students(o能訪問(wèn)Students的原型)
2.student執(zhí)行,執(zhí)行Person的代碼,this是o,并且傳入name, o.name="小明"返回的k是undefined
3.返回o,也就是返回{name:"小明"}

es6繼承
class Person {
}
class Student extends person{
}

在babel es2015-loose模式下編譯后的源碼如下

"use strict";

    function _inheritsLoose(subClass, superClass) {
        subClass.prototype = Object.create(superClass.prototype);
        subClass.prototype.constructor = subClass;
        subClass.__proto__ = superClass;
    }

    var Person = function Person() {
    };

    var Student =
        /*#__PURE__*/
        function (_person) {
            _inheritsLoose(Student, _person);

            function Student() {
                return _person.apply(this, arguments) || this;
            }

            return Student;
        }(person);

嚴(yán)格模式下,高級(jí)單例模式返回一個(gè)Student, 可以看到Person的實(shí)例屬性用的Person的構(gòu)造函數(shù)+apply繼承的
原型屬性用的_inheritsLoose這個(gè)方法繼承的
_inheritsLoose方法貌似就是我們之前說(shuō)的寄生組合繼承

繼承的應(yīng)用:vue數(shù)組變異方法的實(shí)現(xiàn)

我們知道vue里面的數(shù)組有變異方法,變異方法有啥功能呢,就拿push來(lái)說(shuō),一方面數(shù)組會(huì)變,另外一方面有響應(yīng)式(假設(shè)觸發(fā)render方法)
思路:APO編程思想
數(shù)組之所以有push方法,是因?yàn)锳rray.prototype上有push方法
我們需要實(shí)現(xiàn)自己的push方法,掛在Array.prototype上對(duì)原型鏈追蹤進(jìn)行攔截,但是呢又不能改變?cè)玩溕蠈?duì)非變異方法
原型鏈?zhǔn)疽猓?/p>

    Vue里面添加過(guò)監(jiān)控的數(shù)組實(shí)例--->我們自己實(shí)現(xiàn)的變異方法-->原來(lái)的Array.prototype
    
const arrList = ["push","pop","shift","unshfit","reverse","sort","splice"]
const render = ()=>{console.log("響應(yīng)式,渲染視圖")}
const proto = Object.create(Array)
arrList.forEach((method)=>{
    proto[method] = function(){
        render()
        Array.prototype[method].call(this,...arguments)
    }
})
var data = [1,2,3]
data.__proto__ = proto    //mvvm響應(yīng)式原理,如果添加響應(yīng)式的目標(biāo)是數(shù)組,我就執(zhí)行這個(gè)操作

data.push(4)   // 響應(yīng)式,渲染視圖,(data[1,2,3,4])
總結(jié)

本節(jié)詳細(xì)介紹了繼承的原理以及優(yōu)化,對(duì)于es6的繼承語(yǔ)法糖也做了剖析。同時(shí)介紹了一下mvvm下數(shù)組借用繼承實(shí)現(xiàn)響應(yīng)式的用法,由于本人水平有限,如果有什么不對(duì)的地方,歡迎留言指出。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109760.html

相關(guān)文章

  • JS核心識(shí)點(diǎn)梳理——原型繼承(上)

    摘要:同理,原型鏈也是實(shí)現(xiàn)繼承的主要方式的只是語(yǔ)法糖。原型對(duì)象也可能擁有原型,并從中繼承方法和屬性,一層一層以此類推。利用構(gòu)造函數(shù)小明張三張三小明缺點(diǎn)每次實(shí)例化都需要復(fù)制一遍函數(shù)到實(shí)例里面。寄生構(gòu)造函數(shù)模式只有被類出來(lái)的才能用。 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 最近又攀登了一下JS三座大山中的第二...

    villainhr 評(píng)論0 收藏0
  • JS核心識(shí)點(diǎn)梳理——變量篇

    摘要:核心知識(shí)點(diǎn)梳理數(shù)據(jù)篇看了一些資料,結(jié)合高程和對(duì)核心知識(shí)點(diǎn)進(jìn)行了梳理。所以,一共有種聲明變量的方法。凡是在聲明之前就使用這些變量,就會(huì)報(bào)錯(cuò)。還是那句話,建議大家掌握核心知識(shí)點(diǎn),細(xì)枝末節(jié)的東西就隨意啦。 JS核心知識(shí)點(diǎn)梳理——數(shù)據(jù)篇 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 看了一些資料,結(jié)合ES6、高程和MD...

    aristark 評(píng)論0 收藏0
  • JS核心識(shí)點(diǎn)梳理——上文、作用域、閉包、this(中)

    摘要:引言滿滿的干貨,面試必系列,參考大量資料,并集合自己的理解以及相關(guān)的面試題,對(duì)核心知識(shí)點(diǎn)中的作用域閉包上下文進(jìn)行了梳理。本篇重點(diǎn)介紹閉包和。所以,有另一種說(shuō)法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 滿滿的干貨,面試必bei系列,參考大量資料,并集...

    rottengeek 評(píng)論0 收藏0
  • js知識(shí)梳理4.繼承的模式探究

    摘要:而且在超類型的原型中定義的方法,對(duì)子類型而言也是不可見(jiàn)的,結(jié)果所有類型都只能使用構(gòu)造函數(shù)模式。在主要考慮對(duì)象而不是自定義類型和構(gòu)造函數(shù)的情況下,這個(gè)模式也不錯(cuò)。 寫在前面 注:這個(gè)系列是本人對(duì)js知識(shí)的一些梳理,其中不少內(nèi)容來(lái)自書籍:Javascript高級(jí)程序設(shè)計(jì)第三版和JavaScript權(quán)威指南第六版,感謝它們的作者和譯者。有發(fā)現(xiàn)什么問(wèn)題的,歡迎留言指出。 1.原型鏈 將原型鏈作...

    wenshi11019 評(píng)論0 收藏0
  • JS開(kāi)發(fā)中函數(shù)識(shí)點(diǎn)梳理(二)

    摘要:英文原文中本來(lái)是,而翻譯成第一類公民其實(shí)就是一種比喻。所以,通過(guò)上述的結(jié)果,我們發(fā)現(xiàn)在中不管我們是用構(gòu)造函數(shù)創(chuàng)建的對(duì)象還是用本身提供的數(shù)據(jù)類型創(chuàng)建的對(duì)象都源自于。使用可以解除函數(shù)體內(nèi)代碼和函數(shù)名的耦合狀態(tài)。 作為一個(gè)Jser,不光要會(huì)用js,還要明白它的運(yùn)行原理,不然就會(huì)一直停留在表面。 函數(shù)在JavaScript中被稱作第一等公民,這個(gè)第一等公民是什么鬼?看看知乎上是怎么回答的。就像...

    appetizerio 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<