成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【前端芝士樹】Javascript的原型與原型鏈

yy736044583 / 2757人閱讀

摘要:在創(chuàng)建對象不論是普通對象還是函數(shù)對象的時候,都有一個叫做的內(nèi)置屬性,用于指向創(chuàng)建它的構(gòu)造函數(shù)的原型對象,也就是。因?yàn)橐粋€普通對象的構(gòu)造函數(shù)所以原型鏈原型鏈的形成是真正是靠而非。參考文章最詳盡的原型與原型鏈終極詳解,沒有可能是。

【前端芝士樹】Javascript的原型、原型鏈以及繼承機(jī)制
前端的面試中經(jīng)常會遇到這個問題,自己也是一直似懂非懂,趁這個機(jī)會整理一下
0. 為什么會出現(xiàn)原型和原型鏈的概念

1994年,網(wǎng)景公司(Netscape)發(fā)布了Navigator瀏覽器0.9版,但是剛開始的Js沒有繼承機(jī)制,更別提像同時期興盛的C++和Java這樣擁有面向?qū)ο蟮母拍?。在?shí)際的開發(fā)過程中,工程師們發(fā)現(xiàn)沒有繼承機(jī)制很難解決一些問題,必須有一種機(jī)制能將所有的對象關(guān)聯(lián)起來。

Brendan Eich鑒于以上情況,但不想把Js設(shè)計得過為復(fù)雜,于是引入了new關(guān)鍵詞constructor構(gòu)造函數(shù)來簡化對象的設(shè)計,引入了prototype函數(shù)對象來包含所有實(shí)例對象的構(gòu)造函數(shù)的屬性和方法,引入了proto原型鏈的概念解決繼承的問題。

1. Javscript 函數(shù)和函數(shù)對象
var o1 = {}; 
var o2 =new Object();
var o3 = new f1();

function f1(){}; 
var f2 = function(){};
var f3 = new Function("str","console.log(str)");
凡是直接或者間接通過 new Function() 創(chuàng)建的對象都是函數(shù)對象,其他的都是普通對象。

在上面的程序中,o1、o2、o3都是普通對象,f1、f2、f3都是函數(shù)對象。

2. 構(gòu)造函數(shù)
function Person(name, age, job) {
 this.name = name;
 this.age = age;
 this.job = job;
 this.sayName = function() { alert(this.name) } 
}
var person1 = new Person("Zaxlct", 28, "Software Engineer");
var person2 = new Person("Mick", 23, "Doctor");
person1person2 都是 構(gòu)造函數(shù) Person 的實(shí)例。
實(shí)例的構(gòu)造函數(shù)屬性(constructor)指向構(gòu)造函數(shù)。
3. 原型對象
Person.prototype = {
   name:  "Zaxlct",
   age: 28,
   job: "Software Engineer",
   sayName: function() {
     alert(this.name);
   }
}

每個函數(shù)對象都有一個 prototype 屬性,這個屬性就是函數(shù)的原型對象。

每個對象都有 proto 屬性,但只有函數(shù)對象才有 prototype 屬性

在默認(rèn)情況下,所有的原型對象都會自動獲得一個 constructor(構(gòu)造函數(shù))屬性,這個屬性(是一個指針)指向 prototype 屬性所在的函數(shù)(Person)

Person.prototype.constructor == Person

而在Person這個對象進(jìn)行實(shí)例化的時候,實(shí)際上是創(chuàng)建了一個它的實(shí)例對象并賦值給它的 prototype,所以得出以下結(jié)論:

原型對象(Person.prototype)是 構(gòu)造函數(shù)(Person)的一個實(shí)例。
4. _proto_

JS 在創(chuàng)建對象(不論是普通對象還是函數(shù)對象)的時候,都有一個叫做__proto__ 的內(nèi)置屬性,用于指向創(chuàng)建它的構(gòu)造函數(shù)的原型對象,也就是prototype。

Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;

看下面一段代碼

Person.prototype.__proto__ === Object.prototype;

Person.prototype 是一個普通對象,我們無需關(guān)注它有哪些屬性,只要記住它是一個普通對象。
因?yàn)橐粋€ 普通對象的構(gòu)造函數(shù) === Object
所以 Person.prototype.__proto__ === Object.prototype

5. 原型鏈
原型鏈的形成是真正是靠__proto__ 而非prototype。
person1.__proto__ === Person.prototype;
Person.prototype.__proto__ === Object.prototype;
Object.prototype.__proto__ === null;
//Object.prototype.__proto__ === null,保證原型鏈能夠正常結(jié)束。

Person.__proto__ === Function.prototype;
Object.__proto__ === Function.prototype;
Function.prototype.__proto__ === Object.prototype;

前面三項(xiàng)已經(jīng)形成了一個原型鏈,那么后面代碼中Person和Object的__proto__都是Function.prototype呢?

所有函數(shù)對象的proto都指向Function.prototype,它是一個空函數(shù)(Empty function)
Number.__proto__ === Function.prototype  // true
Number.constructor == Function //true

Boolean.__proto__ === Function.prototype // true
Boolean.constructor == Function //true

String.__proto__ === Function.prototype  // true
String.constructor == Function //true

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

Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

Array.__proto__ === Function.prototype   // true
Array.constructor == Function //true

RegExp.__proto__ === Function.prototype  // true
RegExp.constructor == Function //true

Error.__proto__ === Function.prototype   // true
Error.constructor == Function //true

Date.__proto__ === Function.prototype    // true
Date.constructor == Function //true
所有的構(gòu)造器都來自于 Function.prototype,甚至包括根構(gòu)造器Object及Function自身。所有構(gòu)造器都繼承了·Function.prototype·的屬性及方法。如length、call、apply、bind

所以我們再舉一個原型鏈的例子

let num = new Number();
num.__proto__ === Number.prototype;
Number.prototype.__proto__ === Function.prototype;
Funtion.prototype.__proto__ === Object.prototype;
Object.prototype.__proto__ === null;

也可看下圖的實(shí)現(xiàn),更直觀。

ok, 所以明白為什么Number、String、Array這樣的對象實(shí)例能繼承到Object的屬性以及原型鏈?zhǔn)窃趺匆换厥铝税伞?/p>

參考文章
最詳盡的 JS 原型與原型鏈終極詳解,沒有「可能是」。
三張圖搞懂JavaScript的原型對象與原型鏈 - 水乙 - 博客園
Javascript繼承機(jī)制的設(shè)計思想 - 阮一峰的網(wǎng)絡(luò)日志

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98270.html

相關(guān)文章

  • 芝士整理】JS基礎(chǔ)圖譜

    摘要:沒有找到的話,看上級函數(shù)作用域,向上查找到,找到為止。將會在執(zhí)行上下文棧中保留上級作用域的執(zhí)行上下文。若在閉包使用完畢之后不手動解除引用,相關(guān)執(zhí)行上下文將會一直保留于執(zhí)行上下文棧中,占據(jù)內(nèi)存空間,若持續(xù)積累,容易造成內(nèi)存泄漏。 JS有哪些基本數(shù)據(jù)類型呢? 值類型:undefined, Number, Boolean, String,null 引用類型:Object 值類型存放在棧中 引...

    netScorpion 評論0 收藏0
  • 前端性能優(yōu)化(JavaScript補(bǔ)充篇)

    摘要:而像和會增加作用域鏈的長度,所以也會降低性能。但是用獲取一些屬性時,會不由自主地強(qiáng)迫隊(duì)列中的所有渲染事件前不完成。在條件增加時,所帶來的性能負(fù)擔(dān)要高于,因此建議使用。它代價昂貴,且容易失控。 正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來及其無恥的蹭書了~~~ 小廣告:更多內(nèi)容可以看我的博客 以下內(nèi)容均來自《高性能JavaScript》 JavaScript文件加載 ...

    molyzzx 評論0 收藏0
  • 前端性能優(yōu)化(JavaScript補(bǔ)充篇)

    摘要:而像和會增加作用域鏈的長度,所以也會降低性能。但是用獲取一些屬性時,會不由自主地強(qiáng)迫隊(duì)列中的所有渲染事件前不完成。在條件增加時,所帶來的性能負(fù)擔(dān)要高于,因此建議使用。它代價昂貴,且容易失控。 正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來及其無恥的蹭書了~~~ 小廣告:更多內(nèi)容可以看我的博客 以下內(nèi)容均來自《高性能JavaScript》 JavaScript文件加載 ...

    taoszu 評論0 收藏0
  • 前端面試絕對會考JS問題!【已經(jīng)開源】

    摘要:借用構(gòu)造函數(shù)類式繼承借用構(gòu)造函數(shù)雖然解決了剛才兩種問題,但沒有原型,則復(fù)用無從談起。 寫在前面 【前端指南】前端面試庫已經(jīng)開源,正在完善之中 [x] css問題 [x] html問題 [x] javascript問題 github地址 https://github.com/nanhupatar... showImg(https://segmentfault.com/img...

    renweihub 評論0 收藏0
  • 前端面試之JavaScript(總結(jié))

    1. JS基本的數(shù)據(jù)類型和引用類型 基本數(shù)據(jù)類型:number、string、null、undefined、boolean、symbol -- 棧 引用數(shù)據(jù)類型:object、array、function -- 堆 兩種數(shù)據(jù)類型存儲位置不同 原始數(shù)據(jù)類型是直接存儲在棧(stack)中的簡單數(shù)據(jù)段,占據(jù)空間小、大小固定,屬于被頻繁使用數(shù)據(jù); 引用數(shù)據(jù)類型存儲在堆(heap)中的對象,占據(jù)空間大、大...

    tomato 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<