欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文搞懂JavaScript中原型與原型鏈

 更新時(shí)間:2022年10月22日 09:12:37   作者:YinJie…  
js中的原型與原型鏈應(yīng)該是老生常談的話題了,在前端面試中基本都是必問的一個(gè)問題,但是很多人還是稀里糊涂的,只知道其表層含義。本文將帶大家深入了解JavaScript中的原型與原型鏈,感興趣的可以學(xué)習(xí)一下

在ES6之前,我們面向?qū)ο笫峭ㄟ^構(gòu)造函數(shù)實(shí)現(xiàn)的。我們把對(duì)象的公共屬性和方法放在構(gòu)造函數(shù)里

像這樣:

function student(uname,age) {
    this.uname = uname;
    this.age = age;
    this.school = function() {
        console.log('深圳理工大學(xué)');
    }
}
var stu1 = new student('小紅',18);
var stu2 = new student('小紫',20);

但是構(gòu)造函數(shù)方法雖然好用,可他存在浪費(fèi)內(nèi)存的問題。比如在上例中在構(gòu)造函數(shù)里我們有一個(gè)函數(shù),函數(shù)屬于復(fù)雜數(shù)據(jù)類型,他會(huì)單獨(dú)在內(nèi)存中開辟一個(gè)空間。在這里我們創(chuàng)建了兩個(gè)實(shí)例化對(duì)象,那么就會(huì)開辟兩個(gè)內(nèi)存空間來存放同一個(gè)函數(shù),那就造成了內(nèi)存浪費(fèi)的問題。

1.構(gòu)造函數(shù)原型prototype

構(gòu)造函數(shù)通過原型分配的函數(shù)是所有對(duì)象所共享的。

JavaScript規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè)prototype屬性, 指向另一個(gè)對(duì)象。注意這個(gè)prototype就是一個(gè)對(duì)象,這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)所擁有。

我們可以把那些不變的方法,直接定義在prototype對(duì)象上,這樣所有對(duì)象的實(shí)例就可以共享這些方法。

所以在上例中我們就可以把公共函數(shù)放在原型對(duì)象的里面,這樣就不會(huì)造成內(nèi)存浪費(fèi)

function student(uname,age) {
    this.uname = uname;
    this.age = age;
}
student.prototype.school = function() {
    console.log('深圳理工大學(xué)');
}
var stu1 = new student('小紅',18);
var stu2 = new student('小紫',20);

那么我們就明白了原型是什么,他就是一個(gè)對(duì)象,我們稱prototype為原型對(duì)象

原型的作用是什么呢?四個(gè)字,共享方法

2.對(duì)象原型__proto__

對(duì)象都會(huì)有一個(gè)屬性__proto__指向構(gòu)造函數(shù)的 prototype原型對(duì)象,之所以我們對(duì)象可以使用構(gòu)造函數(shù)prototype原型對(duì)象的屬性和方法,就是因?yàn)閷?duì)象有_ proto_ 原型的存在。

在對(duì)象身上系統(tǒng)自己添加了一個(gè)__proto__指向我們構(gòu)造函數(shù)的原型對(duì)象,所以__proto__對(duì)象原型和原型對(duì)象prototype是等價(jià)的。

我們驗(yàn)證一下,看看會(huì)輸出什么:

console.log(stu1.__proto__ === student.prototype);

最后輸出是true證明對(duì)象原型__proto__和原型對(duì)象protptype是等價(jià)的

所以方法的查找規(guī)則就是首先看stu1對(duì)象身上是否有school方法,如果有就執(zhí)行這個(gè)對(duì)象上的school,如果沒有school這個(gè)方法, 因?yàn)橛衉_proto__的存在,就去構(gòu)造函數(shù)原型對(duì)象prototype身上去查找school這個(gè)方法

如果覺得還是不太懂,一圖搞懂你的疑問:

3.constructor構(gòu)造函數(shù)

對(duì)象原型(__proto__) 和構(gòu)造函數(shù)( prototype )原型對(duì)象里面都有一個(gè)屬性 constructor屬性, constructor我們稱為構(gòu)造函數(shù),因?yàn)樗富貥?gòu)造函數(shù)本身。

我們打印一下student.prototype和stu1.__type__看看是否存在constructor屬性:

console.log(student.prototype);
console.log(stu1.__proto__);

可以看到這里面都有constructor,那constructor有什么作用呢?

constructor主要用于記錄該對(duì)象引用于哪個(gè)構(gòu)造函數(shù),它可以讓原型對(duì)象重新指向原來的構(gòu)造函數(shù)

我們知道在原型對(duì)象中我們可以定義那些公共的方法,但是如果公共的方法很多呢,我們通過對(duì)象的形式存儲(chǔ)就方便多了:

student.prototype = {
    school:function() {},
    location:function() {}
}

然后我們輸出一下原型對(duì)象的constructor看看有沒有變化:

console.log(student.prototype.constructor);
console.log(stu1.__proto__.constructor);

最后的輸出結(jié)果是這樣:

這是為什么呢,constructor不應(yīng)該指向我們的student構(gòu)造函數(shù)嗎

因?yàn)槲覀兺ㄟ^student.prototype.school這樣屬于往原型對(duì)象里添加方法,但是我們剛才屬于賦值,這樣就把原先prototype里的東西都覆蓋掉了,這樣student.prototype就沒有constructor了,沒有constructor自然就指回不了student構(gòu)造函數(shù)了

這個(gè)時(shí)候我們就需要手動(dòng)的利用constructor這個(gè)屬性指回原來的構(gòu)造函數(shù)

student.prototype = {
    constructor:student,
    school:function() {},
    location:function() {}
}

我們再輸出一下原型對(duì)象的constructor:

這樣我們就知道這個(gè)對(duì)象到底是通過哪個(gè)構(gòu)造函數(shù)創(chuàng)建出來的了

現(xiàn)在我們更新一下構(gòu)造函數(shù)、實(shí)例、原型對(duì)象三者關(guān)系圖:

4.原型鏈

因?yàn)閟tudent原型對(duì)象也是一個(gè)對(duì)象,我們之前說了只要是對(duì)象就有對(duì)象原型的存在

那我們打印一下原型對(duì)象看看里面是否有原型:

function student(uname,age) {
    this.uname = uname;
    this.age = age;
}
student.prototype.school = function() {
    console.log('深圳理工大學(xué)');
}
var stu1 = new student('小紅',18);
console.log(student.prototype);

輸出結(jié)果:

可以看到原型對(duì)象里也有一個(gè)原型,又因?yàn)樵椭赶虻氖窃蛯?duì)象,那么我們這個(gè)student.prototype里面的__proto__指向的是誰呢?

我們打印一下:

console.log(student.prototype.__proto__);

可以看到指向的是這個(gè)constructor指向的是Object原型對(duì)象

Object原型對(duì)象是由誰創(chuàng)建出來的呢,毫無疑問是Object構(gòu)造函數(shù)創(chuàng)建出來的。那么我們繼續(xù),Object原型對(duì)象也是一個(gè)對(duì)象,那它也有一個(gè)原型,這個(gè)原型指向的又是誰呢?

我們輸出一下:

console.log(Object.prototype.__proto__);

最后的結(jié)果為空:

這樣就到了最頂層了,這樣我們把這些串起來就能得到一個(gè)原型鏈:

5.原型對(duì)象中的this指向

我們知道在構(gòu)造函數(shù)中的this指向的是對(duì)象實(shí)例,那么原型對(duì)象里的函數(shù),這個(gè)函數(shù)里的this指向的是誰呢?

我們聲明一個(gè)全局變量that,把原型對(duì)象里的this賦給that,看看這個(gè)that指向的是不是實(shí)例對(duì)象:

function student(uname,age) {
    this.uname = uname;
    this.age = age;
}
var that;
student.prototype.school = function() {
    that = this;
    console.log('深圳理工大學(xué)');
}
var stu1 = new student('小紅',18);
stu1.school();
console.log(that === stu1);

輸出結(jié)果:

所以原型對(duì)象函數(shù)里面的this指向的也是實(shí)例對(duì)象stu1

6.擴(kuò)展內(nèi)置對(duì)象(原型對(duì)象的應(yīng)用)

我們可以通過原型對(duì)象,對(duì)原來的內(nèi)置對(duì)象進(jìn)行擴(kuò)展自定義的方法。比如給數(shù)組增加自定義求和的功能

我們輸出一下數(shù)組的原型對(duì)象,看看里面有什么方法:

console.log(Array.prototype);

這里沒有給數(shù)組自定義求和的函數(shù),那么我們往數(shù)組的原型對(duì)象里添加這個(gè)方法:

Array.prototype.sum = function() {
    var sum = 0;
    for(var i = 0;i<this.length;i++)
    {
        sum += this[i];
    }
    return sum;
}
var ss = new Array(4,5,3,6);
console.log(ss.sum());

我們自定義的sum方法里,this.length指的就是調(diào)用這個(gè)方法的數(shù)組的長度,因?yàn)樵谏弦还?jié)中我們知道原型對(duì)象函數(shù)里面的this指向的也是實(shí)例對(duì)象

我們通過new方法創(chuàng)建一個(gè)數(shù)組實(shí)例對(duì)象,我們向數(shù)組的原型對(duì)象添加sum方法,那么我們的實(shí)例對(duì)象就可以調(diào)用它。

輸出結(jié)果:

我們再打印一下數(shù)組的原型對(duì)象,看看里面有沒有sum方法:

可以看到sum成功的添加到數(shù)組的原型對(duì)象里了,這樣我們繼續(xù)用到數(shù)組求和時(shí),就可以直接調(diào)用sum方法了。

到此這篇關(guān)于一文搞懂JavaScript中原型與原型鏈的文章就介紹到這了,更多相關(guān)JS原型與原型鏈內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你搞懂JavaScript中數(shù)組的特性

    一文帶你搞懂JavaScript中數(shù)組的特性

    數(shù)組是幾乎所有編程語言的基礎(chǔ)語法,JavaScript因?yàn)檎Z法特性,我們更需要理解數(shù)組知識(shí)。本文從JavaScript中數(shù)組的一些特殊之處入手,通過這些少有特性的詳細(xì)介紹,加深我們對(duì)數(shù)組的理解
    2023-04-04
  • JS判斷對(duì)象屬性是否存在的五種方案分享

    JS判斷對(duì)象屬性是否存在的五種方案分享

    編寫JS的過程中,我們經(jīng)常用到對(duì)象,也會(huì)用到對(duì)象中的屬性,下面這篇文章主要給大家介紹了關(guān)于JS判斷對(duì)象屬性是否存在的五種方案,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • uniapp組件之tab選項(xiàng)卡滑動(dòng)切換功能實(shí)現(xiàn)

    uniapp組件之tab選項(xiàng)卡滑動(dòng)切換功能實(shí)現(xiàn)

    這篇文章主要介紹了uniapp組件之tab選項(xiàng)卡滑動(dòng)切換功能實(shí)現(xiàn),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-01-01
  • JavaScript數(shù)組排序小程序?qū)崿F(xiàn)解析

    JavaScript數(shù)組排序小程序?qū)崿F(xiàn)解析

    這篇文章主要介紹了JavaScript數(shù)組排序小程序?qū)崿F(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • js用閉包遍歷樹狀數(shù)組的方法

    js用閉包遍歷樹狀數(shù)組的方法

    這篇文章主要介紹了js中用閉包遍歷樹狀數(shù)組的方法,需要的朋友可以參考下
    2014-03-03
  • 用javascript實(shí)現(xiàn)檢測指定目錄是否存在的方法

    用javascript實(shí)現(xiàn)檢測指定目錄是否存在的方法

    今天看到一篇關(guān)于onegreen被掛馬的代碼發(fā)現(xiàn)這個(gè)函數(shù),它用js就可以檢測,制定的目錄或指定的文件是否存在,一般用來讀chm文件中的圖片來檢測,目錄的存在。高手就是不學(xué)好。
    2008-01-01
  • 妙用緩存調(diào)用鏈實(shí)現(xiàn)JS方法的重載

    妙用緩存調(diào)用鏈實(shí)現(xiàn)JS方法的重載

    方法重載是指在一個(gè)類中定義多個(gè)同名的方法,但要求每個(gè)方法具有不同的參數(shù)的類型或參數(shù)的個(gè)數(shù)。簡而言之就是:方法重載就是方法名稱重復(fù),加載參數(shù)不同
    2018-04-04
  • Bootstrap縮略圖與警告框?qū)W習(xí)使用

    Bootstrap縮略圖與警告框?qū)W習(xí)使用

    這篇文章主要為大家詳細(xì)介紹了Bootstrap縮略圖與警告框?qū)W習(xí)使用的相關(guān)資料,希望通過這篇文章和大家更多的去學(xué)習(xí)Bootstrap縮略圖與警告框,從中得到收獲
    2017-02-02
  • JavaScript Window瀏覽器對(duì)象模型原理解析

    JavaScript Window瀏覽器對(duì)象模型原理解析

    這篇文章主要介紹了JavaScript Window瀏覽器對(duì)象模型,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • js判斷一個(gè)對(duì)象是數(shù)組(函數(shù))的方法實(shí)例

    js判斷一個(gè)對(duì)象是數(shù)組(函數(shù))的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于利用js如何判斷一個(gè)對(duì)象是數(shù)組(函數(shù))的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JS具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評(píng)論