成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

js 原型鏈的那些事兒

fuyi501 / 3461人閱讀

摘要:原型鏈?zhǔn)紫龋膶?duì)象普通對(duì)象和函數(shù)對(duì)象都會(huì)有屬性,指向創(chuàng)建它的構(gòu)造函數(shù)的原型對(duì)象,比如上面的例子這就形成了原型鏈,會(huì)一直查找原型對(duì)象的屬性,直到為。,保證原型鏈能夠正常結(jié)束。

前言

一般談到j(luò)s中的繼承的時(shí)候,一定會(huì)遇到原型,原型鏈的問(wèn)題,原型里面又有prototype,__proto__,constructor屬性,講到這兒,很多同學(xué)是不是都一頭霧水,傻傻分不清楚,因?yàn)楣ぷ髦杏玫降牡胤绞巧僦稚伲偌由蟚s6又出了extends語(yǔ)法糖,更加不用理會(huì)之,但是對(duì)于理解繼承,原型和原型鏈?zhǔn)呛苤匾模斫夂瘮?shù)和對(duì)象,理解prototype和__proto__,construct之間的關(guān)系尤為重要,不過(guò)本文對(duì)繼承不予以深究,另起一篇文章寫之,今天我們只討論js中的原型和原型鏈。

首先,容在下提出一個(gè)問(wèn)題。
到底prototype和__proto__是不是指同一個(gè)東西呢?
答案自然非也。

還有一個(gè)問(wèn)題,就是ie8,9下是沒(méi)有__proto__的概念的,如何解決這個(gè)問(wèn)題?
這個(gè)問(wèn)題在這篇文章結(jié)束之前會(huì)說(shuō)明。

現(xiàn)在我們先來(lái)分析js中的對(duì)象。
js中對(duì)象是很重要的,所謂萬(wàn)物皆對(duì)象,但是js中對(duì)象分為兩種,普通對(duì)象和函數(shù)對(duì)象

普通對(duì)象和函數(shù)對(duì)象

先來(lái)看幾個(gè)例子

 function f1(){};
 var f2 = function(){};
 var f3 = new Function("str","console.log(str)");

 var o3 = new f1();
 var o1 = {};
 var o2 = new Object();

 console.log(typeof Object); //function
 console.log(typeof Function); //function
 console.log(typeof o1); //object
 console.log(typeof o2); //object
 console.log(typeof o3); //object
 console.log(typeof f1); //function
 console.log(typeof f2); //function
 console.log(typeof f3); //function 

在上面的例子中,o1 o2 o3 為普通對(duì)象,f1 f2 f3 為函數(shù)對(duì)象。
那么怎么區(qū)分普通對(duì)象和函數(shù)對(duì)象呢?
其實(shí)很簡(jiǎn)單,凡是通過(guò)new Function()創(chuàng)建的對(duì)象都是函數(shù)對(duì)象,其他的都是普通對(duì)象。f1,f2,歸根結(jié)底都是通過(guò) new Function()的方式進(jìn)行創(chuàng)建的。Function Object 也都是通過(guò) New Function()創(chuàng)建的。

原型對(duì)象

接下來(lái)先說(shuō)一下原型對(duì)象
在js中,每當(dāng)定義一個(gè)對(duì)象的時(shí)候,對(duì)象中都會(huì)包含一些預(yù)定義的屬性。其中函數(shù)對(duì)象的一個(gè)屬性就是原型對(duì)象prototype
普通對(duì)象沒(méi)有prototype,只有__proto__屬性,看下面的例子

function f1(){};
 console.log(f1.prototype) //{constructor:? f1(),__proto__:Object}
 console.log(typeof f1.prototype) //Object
 console.log(typeof Function.prototype) // Function,這個(gè)特殊,因?yàn)镕unction是通過(guò)new Function創(chuàng)建的
 console.log(typeof Object.prototype) // Object
 console.log(typeof Function.prototype.prototype) //undefined

從console.log(f1.prototype) //{constructor:? f1(),__proto__:Object}可以看出f1.prototype就是f1的一個(gè)實(shí)例對(duì)象,就是在創(chuàng)建f1的時(shí)候,創(chuàng)建了一個(gè)它的實(shí)例對(duì)象,并把它賦給了prototype原型對(duì)象。代碼如下

const temp = new f1();
f1.prototype = temp;

那么看到這兒,大家肯定會(huì)說(shuō),為什么要有原型對(duì)象?這個(gè)原型對(duì)象有什么用?
剛開始我就提到了,繼承里會(huì)用到。看下下面的代碼:

function Cat(name){
    this.name = name;
}
Cat.prototype.getName = function(){
    alert(this.name);
}
const qqq = new Cat("qqq");
qqq.getName();//qqq

從上面的代碼中可以看出,通過(guò)給Cat的原型對(duì)象添加屬性方法,那么Cat的實(shí)例都會(huì)擁有這個(gè)方法并可以調(diào)用之。有同學(xué)可能會(huì)有疑問(wèn),為什么在原型對(duì)象上添加了屬性方法,它的實(shí)例就也可以擁有這個(gè)方法呢?這就牽扯到接下來(lái)說(shuō)到的原型鏈了。

原型鏈

首先,js的對(duì)象(普通對(duì)象和函數(shù)對(duì)象)都會(huì)有__proto__屬性,指向創(chuàng)建它的構(gòu)造函數(shù)的原型對(duì)象,比如上面的例子

qqq.__proto__ === Cat.prototype;//true
Cat.prototype.__proto__ === Object.prototype;//true
Object.prototype.__proto__//null 

這就形成了原型鏈,會(huì)一直查找原型對(duì)象的__proto__屬性,直到為null。
有幾個(gè)比較特殊的例子,來(lái)看一下
1.Object.__proto__ === Function.prototype // true
Object是函數(shù)對(duì)象,是通過(guò)new Function()創(chuàng)建,所以O(shè)bject.__proto__指向Function.prototype。
2.Function.__proto__ === Function.prototype // true
Function 也是對(duì)象函數(shù),也是通過(guò)new Function()創(chuàng)建,所以Function.__proto__指向Function.prototype。
3.Function.prototype.__proto__ === Object.prototype //true
Function.prototype是個(gè)函數(shù)對(duì)象,理論上他的__proto__應(yīng)該指向 Function.prototype,就是他自己,自己指向自己,沒(méi)有意義。
JS一直強(qiáng)調(diào)萬(wàn)物皆對(duì)象,函數(shù)對(duì)象也是對(duì)象,給他認(rèn)個(gè)祖宗,指向Object.prototype。Object.prototype.__proto__ === null,保證原型鏈能夠正常結(jié)束。

constructor

constructor是這么定義的。
在 Javascript 語(yǔ)言中,constructor 屬性是專門為 function 而設(shè)計(jì)的,它存在于每一個(gè) function 的prototype 屬性中。這個(gè) constructor 保存了指向 function 的一個(gè)引用。

 Cat.prototype.constructor === Cat //true
 Function.prototype.constructor === Function //true
 Object.prototype.constructor === Object //true

這里也有要注意的
1.注意Object.constructor===Function;//true 本身Object就是Function函數(shù)構(gòu)造出來(lái)的
2.如何查找一個(gè)對(duì)象的constructor,就是在該對(duì)象的原型鏈上尋找碰到的第一個(gè)constructor屬性所指向的對(duì)象

總結(jié)

1.原型和原型鏈?zhǔn)菍?shí)現(xiàn)繼承的一種方式
2.原型鏈真正的繼承是靠__proto__,而不是prototype,且看以下這個(gè)例子

var animal = function(name){
   this.name = name;
}
var cat = function(){};
animal.say = "lalala";
cat.prototype = animal;
var ca = new cat();
console.log(cat.say);//undefined
console.log(ca.say);//lalala

從輸出結(jié)果可以看出,雖然cat的prototype指向了animal,但是讀取say屬性的時(shí)候并不會(huì)根據(jù)prototype找,ca本身雖然也沒(méi)有say屬性,但是看下面這段代碼

ca.__proto__ = cat.prototype
cat.prototype = animal

所以ca.say輸出lalala
3.之前遺留的問(wèn)題,關(guān)于兼容ie的__proto__
ie9有Object.getPrototypeof()方法

   function a(){console.log("aaa")};
   const b = new a();
   Object.getPrototypeof(b) === b.__proto__//true

ie8不支持Object.getPrototypeof方法,可以結(jié)合constructor和prototype

   function a(){console.log("aaa")};
   const b = new a();
   b.constructor.prototype === b.__proto__//true

最后再思考下new()過(guò)程都做了些什么?(比如new A())

創(chuàng)建新對(duì)象var obj = {};

將新對(duì)象的construct屬性指向構(gòu)造函數(shù),__proto__屬性指向構(gòu)造函數(shù)的prototype

執(zhí)行構(gòu)造函數(shù),A.call(obj),將this指向obj

返回新對(duì)象(注意:如果構(gòu)造函數(shù)返回this,基本類型或者不返回,就是返回新對(duì)象,如果返回引用類型,就是返回引用類型)

好了,今天就先寫這么多,明天結(jié)合今天的原型和原型鏈總結(jié)下繼承以及每個(gè)繼承的優(yōu)缺點(diǎn)~~~

參考資料

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

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

相關(guān)文章

  • JS基礎(chǔ)】原型對(duì)象的那些事(二)

    摘要:只是構(gòu)造函數(shù)上的一個(gè)屬性,它是一個(gè)指針,指向原型對(duì)象,并不表示就是原型對(duì)象。在上一個(gè)例子中,就是一個(gè)對(duì)象,這個(gè)對(duì)象可以說(shuō)是原生構(gòu)造函數(shù)的實(shí)例,所以也是一個(gè)對(duì)象,所以它也有屬性,不過(guò)它的指向也就是原型鏈的頂端,再往上就沒(méi)有了。 上一篇講了①原型對(duì)象是什么;②__proto__、prototype、constructor的關(guān)系;③原型對(duì)象的作用;④原型對(duì)象帶來(lái)的一些需要注意的問(wèn)題; 沒(méi)理解...

    yanbingyun1990 評(píng)論0 收藏0
  • 2019前端面試那些事兒

    摘要:雖然今年沒(méi)有換工作的打算但為了跟上時(shí)代的腳步還是忍不住整理了一份最新前端知識(shí)點(diǎn)知識(shí)點(diǎn)匯總新特性,語(yǔ)義化瀏覽器的標(biāo)準(zhǔn)模式和怪異模式和的區(qū)別使用的好處標(biāo)簽廢棄的標(biāo)簽,和一些定位寫法放置位置和原因什么是漸進(jìn)式渲染模板語(yǔ)言原理盒模型,新特性,偽 雖然今年沒(méi)有換工作的打算 但為了跟上時(shí)代的腳步 還是忍不住整理了一份最新前端知識(shí)點(diǎn) 知識(shí)點(diǎn)匯總1.HTMLHTML5新特性,語(yǔ)義化瀏覽器的標(biāo)準(zhǔn)模式和怪...

    JeOam 評(píng)論0 收藏0
  • 2019前端面試那些事兒

    摘要:雖然今年沒(méi)有換工作的打算但為了跟上時(shí)代的腳步還是忍不住整理了一份最新前端知識(shí)點(diǎn)知識(shí)點(diǎn)匯總新特性,語(yǔ)義化瀏覽器的標(biāo)準(zhǔn)模式和怪異模式和的區(qū)別使用的好處標(biāo)簽廢棄的標(biāo)簽,和一些定位寫法放置位置和原因什么是漸進(jìn)式渲染模板語(yǔ)言原理盒模型,新特性,偽 雖然今年沒(méi)有換工作的打算 但為了跟上時(shí)代的腳步 還是忍不住整理了一份最新前端知識(shí)點(diǎn) 知識(shí)點(diǎn)匯總1.HTMLHTML5新特性,語(yǔ)義化瀏覽器的標(biāo)準(zhǔn)模式和怪...

    QLQ 評(píng)論0 收藏0
  • 漫談 | 從姓名巫術(shù)說(shuō)起,聊聊區(qū)塊鏈匿名那些事兒

    摘要:無(wú)獨(dú)有偶,在中國(guó)古代社會(huì),也有姓名巫術(shù)這一說(shuō)。從匿名到偽匿名此時(shí),具有匿名性的區(qū)塊鏈走入了人們的視野,除了去中心化安全性可追溯性等特征外,區(qū)塊鏈被提及最多的就是其匿名性。因此,區(qū)塊鏈的完全匿名或完全實(shí)名是不可能的。 從姓名巫術(shù)到匿名文化 姓名,是一個(gè)人最基礎(chǔ)的社會(huì)符號(hào),是人們相互了解的一個(gè)窗口。然而,在科技落后的古代,人們對(duì)名字被人知曉諱莫如深。因?yàn)樗麄冋J(rèn)為,姓名與靈魂共生。 在印第安...

    Carl 評(píng)論0 收藏0
  • [聊一聊系列]聊一聊百度移動(dòng)端首頁(yè)前端速度那些事兒

    摘要:要快,但是我們的服務(wù)也必須萬(wàn)無(wú)一失,后續(xù)我會(huì)分享百度移動(dòng)端首頁(yè)的前端架構(gòu)設(shè)計(jì)那么這樣的優(yōu)化,是如何做到的呢,又如何兼顧穩(wěn)定性,架構(gòu)性,與速度呢別急,讓我們把這些優(yōu)化一一道來(lái)。百度移動(dòng)端首頁(yè)的很多就是這樣緩存在客戶端的。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog/fronte...

    The question 評(píng)論0 收藏0

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

0條評(píng)論

閱讀需要支付1元查看
<