成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Javascript原型和原型鏈的知識(shí)點(diǎn)整理

這篇文章主要講解了“Javascript原型和原型鏈的知識(shí)點(diǎn)整理”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Javascript原型和原型鏈的知識(shí)點(diǎn)整理”吧!

目前創(chuàng)新互聯(lián)已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、井岡山網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

前言

在前端這塊領(lǐng)域,原型與原型鏈?zhǔn)敲恳粋€(gè)前端er必須掌握的概念。我們多次在面試或者一些技術(shù)博客里面看見(jiàn)這個(gè)概念。由此可見(jiàn),這個(gè)玩意對(duì)于前端來(lái)說(shuō)有多重要。其實(shí)它本身理解起來(lái)不難,但是很多剛?cè)胄星岸说耐瑢W(xué),看到prototype、__proto__理解起來(lái)還是有點(diǎn)吃力,然后腦子里面就亂成一鍋粥,就像我一樣。但是這是很正常的事情,沒(méi)什么大不了的,就像我們想要學(xué)會(huì)跑步,那么我們就必須先學(xué)會(huì)走路。任何事情都是有個(gè)過(guò)程的。所以現(xiàn)在就跟我一起來(lái)攻克這個(gè)難點(diǎn)吧。通過(guò)這篇文章你將掌握以下知識(shí)點(diǎn):

  • 理解 __proto_;

  • 理解 prototype;

  • 理解javascript中對(duì)象的概念;

  • 理解原型和原型鏈;

  • 理解javascript中類的概念;

  • 理解new的實(shí)現(xiàn);

  • 理解instanceof的實(shí)現(xiàn);

  • 理解javascript的繼承;

  • 加深對(duì)javascript這門(mén)語(yǔ)言的理解。

這也是本篇文章的寫(xiě)作思路。

對(duì)象

那么我們就從對(duì)象這一概念開(kāi)始說(shuō)起,其實(shí)對(duì)象這一概念相信大家并不陌生。有一種說(shuō)法是“javasrcript中萬(wàn)物皆是對(duì)象”,其實(shí)這個(gè)說(shuō)法是錯(cuò)誤的,一個(gè)很簡(jiǎn)單的例子,javasript中簡(jiǎn)單基本類型(string、boolean、number、null、undefined、symbol)本身就不是對(duì)象。其實(shí)javasript中對(duì)象主要分為函數(shù)對(duì)象和普通對(duì)象。其中:

  • String

  • Number

  • Boolean

  • Object

  • Function

  • Array

  • Date

  • RegExp

  • Error

這些都是函數(shù)對(duì)象,他們同時(shí)也被稱為內(nèi)置對(duì)象。函數(shù)對(duì)象本身其實(shí)就是一個(gè)純函數(shù),javascript用他們來(lái)模擬類。普通對(duì)象就很簡(jiǎn)單了,就是我們常見(jiàn)的對(duì)象:

const obj = {     name: 'juefei',     desc: 'cool' }

可能說(shuō)到這,你還是無(wú)法理解到底啥是函數(shù)對(duì)象,啥是普通對(duì)象,那我們就一起來(lái)看看下面的代碼:

const obj1 = {}; const obj2 = new Object(); function func1() {  } const obj3 = new func1(); const func2 = new function() {  } const func3 = new Function()

接著我們來(lái)分別打印一下他們:

console.log(obj1);  // object console.log(obj2);  // object console.log(obj3);  // object console.log(func1);  // function console.log(func2);  // function console.log(func3);  // function

所以可以看見(jiàn),obj1、obj2、,obj3是普通對(duì)象,他們都是Object的實(shí)例,而func1、func2、func3則都是Function的實(shí)例,稱為函數(shù)對(duì)象。我們?cè)倏纯?

console.log(typeof Object);  //f unction console.log(typeof Function); // function

你是不是驚呆了,原來(lái)Object和Function都是 Function的實(shí)例。所以我們得出一個(gè)結(jié)論就是:

  • 只要是Function的實(shí)例,那就是函數(shù)對(duì)象,其余則為普通對(duì)象。

同樣我們也可以看出,不僅 Object 是函數(shù)對(duì)象,就連 Function 本身也是函數(shù)對(duì)象,因?yàn)槲覀兺ㄟ^(guò) console.log(typeof  Function); 得知 Function 是 Function 的實(shí)例。是不是又開(kāi)始有點(diǎn)繞了?沒(méi)事,到這一步你就記住我們剛剛的結(jié)論就算完成目標(biāo):

  • 只要是Function的實(shí)例,那就是函數(shù)對(duì)象,其余則為普通對(duì)象。

那么說(shuō)到對(duì)象,我們從上面可以看出,一個(gè)對(duì)象是通過(guò)構(gòu)造函數(shù) new 出來(lái)的,這其實(shí)跟原型和原型鏈有很大的關(guān)系,那么原型和原型鏈到底是用來(lái)干嘛的呢?

原型

涉及到這兩個(gè)概念,我們就必須先來(lái)介紹兩個(gè)東西: __proto__ 和 prototype ,這兩個(gè)變量可以說(shuō),在 javascript  這門(mén)語(yǔ)言里面隨處可見(jiàn),我們不管他三七二十一,我們先來(lái)看一張表:

Javascript原型和原型鏈的知識(shí)點(diǎn)整理

所以,請(qǐng)你先記住以下結(jié)論:

  • 只有函數(shù)對(duì)象有 prototype 屬性,普通對(duì)象 沒(méi)有這個(gè)屬性。

  • 函數(shù)對(duì)象 和 普通對(duì)象 都有 __proto__這個(gè)屬性。

  • prototype 和 __proto__都是在創(chuàng)建一個(gè)函數(shù)或者對(duì)象會(huì)自動(dòng)生成的屬性。

接著我們來(lái)驗(yàn)證一下:

function func (){  //func稱為構(gòu)造函數(shù)  } console.log( typeof func.prototype); // object console.log(typeof func.__proto__);  // function
const obj = {} console.log(typeof obj.__proto__) //object console.log(typeof obj.prototype) //undefined (看見(jiàn)了吧,普通對(duì)象真的沒(méi)有 prototype 屬性)

所以就驗(yàn)證了我們剛剛的結(jié)論:

  • 只有函數(shù)對(duì)象有 prototype 屬性,普通對(duì)象 沒(méi)有這個(gè)屬性

  • 函數(shù)對(duì)象 和 普通對(duì)象 都有 __proto__這個(gè)屬性。

  • prototype 和 __proto__都是在創(chuàng)建一個(gè)函數(shù)或者對(duì)象會(huì)自動(dòng)生成的屬性。

你看我又重復(fù)寫(xiě)了一遍,我不是為了湊字?jǐn)?shù),是為了你加深記憶,這對(duì)于我們接下來(lái)的篇幅很重要。接著我們來(lái)看看下面的代碼:

console.log(obj.__proto__ === Object.prototype); // true console.log(func.__proto__ === Function.prototype); // true

所以我們又得出如下結(jié)論:

  • 實(shí)例的 __proto__屬性主動(dòng)指向構(gòu)造的 prototype;

  • prototype 屬性被 __proto__ 屬性 所指向。

這就是prototype 屬性和 __proto__ 屬性的區(qū)別與聯(lián)系。這可能又有點(diǎn)繞了,來(lái)多看幾遍這一節(jié),多背一下我們的結(jié)論。我們繼續(xù)。

那么問(wèn)題來(lái)了,既然func是一個(gè)函數(shù)對(duì)象,函數(shù)對(duì)象是有 prototype 屬性的,那么func.prototype.__proto__等于啥呢?

為了解決這個(gè)問(wèn)題,我們來(lái)思考一下:

首先,我們看看func.prototype 是啥:

console.log(typeof func.prototype); //object

好,我們知道了,func.prototype 是一個(gè)對(duì)象,那既然是對(duì)象,那 func.prototype 那不就是  Object的實(shí)例嗎?那也就是說(shuō),func.prototype.__proto__屬性肯定是指向 Object.prototype  咯!好,我們來(lái)驗(yàn)證一下:

console.log(func.prototype.__proto__ === Object.prototype); //true

看見(jiàn)沒(méi)有,就是這樣的。那看到這里,我們應(yīng)該也知道當(dāng)我們這創(chuàng)建一個(gè)構(gòu)造函數(shù)的時(shí)候,javascript是如何幫我們自動(dòng)生成__proto__和prototype屬性的。哈哈沒(méi)錯(cuò)就是這樣:

//我們手動(dòng)創(chuàng)建func函數(shù) function func() {} //javascript悄悄咪咪執(zhí)行以下代碼: func._proto = Function.prototype; //實(shí)例的 __proto__ 屬性主動(dòng)指向構(gòu)造的 prototype func.prototype = {     constructor: func,     __proto: Object.prototype //我們剛剛才在上面驗(yàn)證的,你別又忘記了 }

我還專門(mén)為你畫(huà)了個(gè)圖(夠貼心不老鐵):

 Javascript原型和原型鏈的知識(shí)點(diǎn)整理

所以prototype又被稱為顯式原型對(duì)象,而__proto__又被稱為隱式原型對(duì)象。

hi,看到這里,你是不是有種腦子開(kāi)了光的感覺(jué)。哈哈,所以到現(xiàn)在你應(yīng)該已經(jīng)理解原型的概念了,如果你還不理解,那就把上述章節(jié)再看一遍。最好拿個(gè)紙筆出來(lái)跟著畫(huà)一畫(huà),順便拿出電腦把示例代碼敲一敲。好,整理一下頭腦,接下來(lái)我們來(lái)看看什么又是原型鏈。

原型鏈

再介紹這個(gè)概念之前,我們先來(lái)看如下代碼:

function Person = function(name,desc){     this.name = name;     this.desc = desc; } //***1****// Person.prototype.getName = function(){     return this.name; }//***2****// Person.prototype.getDesc = function(){     return this.desc; }//***3****//  const obj = new Person('juefei','cool');//***4****// console.log(obj);//***5****// console.log(obj.getName);//***6****//

接下來(lái)我們來(lái)逐步解析一下:

1.創(chuàng)建了一個(gè)構(gòu)造函數(shù) Person,此時(shí),Person.portotype自動(dòng)創(chuàng)建,其中包含了 constructor 和  __proto__兩個(gè)屬性;

2.給對(duì)象 Person.prototype 新增了一個(gè)方法 getName;

3.給對(duì)象 Person.prototype 新增了一個(gè)方法 getDesc;

4.構(gòu)造函數(shù) Person 新建一個(gè)實(shí)例: obj(在創(chuàng)建實(shí)例的時(shí)候,構(gòu)造函數(shù)會(huì)自動(dòng)執(zhí)行);

5.打印實(shí)例 obj :

{     name: 'juefei',     desc: 'cool' }

根據(jù)上面一節(jié)的結(jié)論,我們得出:

obj.__proto__ = Person.prototype;

6.執(zhí)行到第6步時(shí),由于在實(shí)例 obj 上面找不到 getName()這個(gè)方法,所以它就會(huì)自動(dòng)去通過(guò)自身的 __proto__ 繼續(xù)向上查找,結(jié)果找到了  Person.prototype ,接著它發(fā)現(xiàn),剛好 Person.prototype  上面有g(shù)etName()方法,于是找到了這個(gè)方法,它就停止了尋找。怎么樣,是不是有一種環(huán)環(huán)相扣的感覺(jué)?他們形成一個(gè)鏈了,沒(méi)錯(cuò),這就是原型鏈。

我們得出如下結(jié)論:

在訪問(wèn)一個(gè)對(duì)象(假設(shè)這個(gè)對(duì)象叫obj)的屬性/方法時(shí),若在當(dāng)前的對(duì)象上面找不到,則會(huì)嘗試通過(guò)obj.__proto__去尋找,而  obj.__proto__ 又指向其構(gòu)造函數(shù)(假設(shè)叫objCreated)的 prototype,所以它又自動(dòng)去 objCreated.prototype  的屬性/方法上面去找,結(jié)果還是沒(méi)找到,那么就訪問(wèn)  objCreated.prototype.__proto__繼續(xù)往上面尋找,直到找到,則停止對(duì)原型鏈對(duì)尋找,若最終還是沒(méi)能找到,則返回 undefined  。一直沿著原型鏈尋找下去,直到找到 Object.prototype.__proto__,指向 null,于是返回 undefined了。

是不是自然而然就理解了。我又給你畫(huà)了個(gè)圖(請(qǐng)對(duì)照著上面?那個(gè)圖看):

Javascript原型和原型鏈的知識(shí)點(diǎn)整理

接下來(lái)我們?cè)賮?lái)增加一些概念:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2. 任何內(nèi)置函數(shù)對(duì)象本身的 __proto__屬性都指向 Function的原型對(duì)象,即: Function.prototype;

  3. 除了 Object.prototype.__proto__指向 null ,所有的內(nèi)置函數(shù)對(duì)象的原型對(duì)象的 __proto__屬性 (  內(nèi)置函數(shù)對(duì)象.prototype.__proto__),都指向Object。

我們得出如下終極原型鏈的圖:

Javascript原型和原型鏈的知識(shí)點(diǎn)整理

針對(duì)這個(gè)圖,我最終給出我們經(jīng)常看見(jiàn)那個(gè)原型鏈的圖:

Javascript原型和原型鏈的知識(shí)點(diǎn)整理

好好對(duì)比一下,拿出紙和筆畫(huà)一畫(huà),根據(jù)上面章節(jié)的講解,相信你很容易就能明白。

javascript中的類

剛剛我們終于明白什么是 原型 和  原型鏈。下面我們根據(jù)上面的概念來(lái)講解一下javascript中的類。我們知道,在面向?qū)ο蟮恼Z(yǔ)言中,類可以被實(shí)例化多次,這個(gè)實(shí)例化是指我們可以根據(jù)構(gòu)造函數(shù)去獨(dú)立復(fù)制多個(gè)獨(dú)立的實(shí)例,這些實(shí)例之間是獨(dú)立的。但是實(shí)際上在  javascript  卻不是這樣的,因?yàn)樗皇沁@種復(fù)制機(jī)制。我們不能創(chuàng)建一個(gè)類的多個(gè)實(shí)例,我們只能創(chuàng)建這個(gè)類的多個(gè)對(duì)象,因?yàn)樗麄兌际峭ㄟ^(guò)原型和原型鏈關(guān)聯(lián)到同一個(gè)對(duì)象。所以在  javascript 中 ,類都是通過(guò)原型和原型鏈來(lái)實(shí)現(xiàn)的,它其實(shí)是一種委托方式。

new的實(shí)現(xiàn)

了解了上面javascript中的類的概念,那我們應(yīng)該很容易就理解new的過(guò)程,其核心無(wú)非就是執(zhí)行原型鏈的鏈接:

function myNew(Cons,...args){     let obj = {};     obj.__proto__ = Cons.prototype; //執(zhí)行原型鏈接     let res = Cons.call(obj,args);     return typeof res === 'object' ? res : obj; }

instanceof的實(shí)現(xiàn)

那么學(xué)習(xí)了原型和原型鏈,instanceof的實(shí)現(xiàn)肯定也很簡(jiǎn)單了,它也是通過(guò)原型和原型鏈來(lái)實(shí)現(xiàn)的:

function myInstanceof(left,right){      let rightProto = right.prototype;      let leftValue = left.__proto__;      while(true){          if(leftValue === null){              return false;          }          if(leftValue === rightProto){              return true;          }          leftValue = leftValue.__proto__;      }  }

我就不講解過(guò)程了,因?yàn)槲抑滥憧隙芸炊?,哈哈?/p>

javascript的繼承

我們都知道繼承也是通過(guò)原型和原型鏈來(lái)實(shí)現(xiàn)的,那我在這里介紹兩種常見(jiàn)的繼承方式:

1.組合繼承:

//組合式繼承 //通過(guò)call繼承Parent的屬性,并傳入?yún)?shù) //將Child的原型對(duì)象指向Parent的實(shí)例,從而繼承Parent的函數(shù)  function Parent(value){      this.val = value;  }  Parent.prototype.getValue = function(){      console.log(this.val);  }  function Child(value){      Parent.call(this,value);//繼承Parentd的屬性  }  Child.prototype = new Parent();

2.寄生組合式繼承:

//寄生組合式繼承 //通過(guò)call繼承Parent的屬性,并傳入?yún)?shù) //通過(guò)Object.create()繼承Parent的函數(shù)   function Parent(value){       this.val = value;   }   Parent.prototype.getValue = function(){       console.log(this.val);   }   function Child(value){       //繼承Parentd的屬性       Parent.call(this,value);   }   Child.prototype = Object.create(Parent.prototype,{       constructor:{           value:Child,           writable:true,           configurable:true,           enumerable:false       }   })

總結(jié)

  1. 若 A 通過(guò) new 創(chuàng)建了 B,則 B.__proto__ = A.prototype;

  2. 執(zhí)行B.a,若在B中找不到a,則會(huì)在B.__proto__中,也就是A.prototype中查找,若A.prototype中仍然沒(méi)有,則會(huì)繼續(xù)向上查找,最終,一定會(huì)找到Object.prototype,倘若還找不到,因?yàn)镺bject.prototype.__proto__指向null,因此會(huì)返回undefined;

  3. 原型鏈的頂端,一定有 Object.prototype.__proto__ ——> null。

感謝各位的閱讀,以上就是“Javascript原型和原型鏈的知識(shí)點(diǎn)整理”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Javascript原型和原型鏈的知識(shí)點(diǎn)整理這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站欄目:Javascript原型和原型鏈的知識(shí)點(diǎn)整理
URL標(biāo)題:http://jinyejixie.com/article40/gdpheo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)公司、企業(yè)建站、定制網(wǎng)站定制開(kāi)發(fā)、動(dòng)態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
错那县| 青海省| 万全县| 金塔县| 滕州市| 深水埗区| 甘泉县| 南通市| 汾西县| 达拉特旗| 无为县| 延庆县| 达拉特旗| 搜索| 壤塘县| 光泽县| 旅游| 万盛区| 望江县| 怀柔区| 平江县| 昌黎县| 辉县市| 定安县| 荃湾区| 大港区| 会同县| 年辖:市辖区| 互助| 屯留县| 浦东新区| 涟源市| 独山县| 阿坝县| 盐津县| 石渠县| 石景山区| 车致| 松潘县| 广德县| 托克逊县|