91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Javascript原型和原型鏈的知識點整理

發布時間:2021-08-18 10:44:21 來源:億速云 閱讀:145 作者:chen 欄目:web開發

這篇文章主要講解了“Javascript原型和原型鏈的知識點整理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Javascript原型和原型鏈的知識點整理”吧!

前言

在前端這塊領域,原型與原型鏈是每一個前端er必須掌握的概念。我們多次在面試或者一些技術博客里面看見這個概念。由此可見,這個玩意對于前端來說有多重要。其實它本身理解起來不難,但是很多剛入行前端的同學,看到prototype、__proto__理解起來還是有點吃力,然后腦子里面就亂成一鍋粥,就像我一樣。但是這是很正常的事情,沒什么大不了的,就像我們想要學會跑步,那么我們就必須先學會走路。任何事情都是有個過程的。所以現在就跟我一起來攻克這個難點吧。通過這篇文章你將掌握以下知識點:

  • 理解 __proto_;

  • 理解 prototype;

  • 理解javascript中對象的概念;

  • 理解原型和原型鏈;

  • 理解javascript中類的概念;

  • 理解new的實現;

  • 理解instanceof的實現;

  • 理解javascript的繼承;

  • 加深對javascript這門語言的理解。

這也是本篇文章的寫作思路。

對象

那么我們就從對象這一概念開始說起,其實對象這一概念相信大家并不陌生。有一種說法是“javasrcript中萬物皆是對象”,其實這個說法是錯誤的,一個很簡單的例子,javasript中簡單基本類型(string、boolean、number、null、undefined、symbol)本身就不是對象。其實javasript中對象主要分為函數對象和普通對象。其中:

  • String

  • Number

  • Boolean

  • Object

  • Function

  • Array

  • Date

  • RegExp

  • Error

這些都是函數對象,他們同時也被稱為內置對象。函數對象本身其實就是一個純函數,javascript用他們來模擬類。普通對象就很簡單了,就是我們常見的對象:

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

可能說到這,你還是無法理解到底啥是函數對象,啥是普通對象,那我們就一起來看看下面的代碼:

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

接著我們來分別打印一下他們:

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

所以可以看見,obj1、obj2、,obj3是普通對象,他們都是Object的實例,而func1、func2、func3則都是Function的實例,稱為函數對象。我們再看看:

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

你是不是驚呆了,原來Object和Function都是 Function的實例。所以我們得出一個結論就是:

  • 只要是Function的實例,那就是函數對象,其余則為普通對象。

同樣我們也可以看出,不僅 Object 是函數對象,就連 Function 本身也是函數對象,因為我們通過 console.log(typeof  Function); 得知 Function 是 Function 的實例。是不是又開始有點繞了?沒事,到這一步你就記住我們剛剛的結論就算完成目標:

  • 只要是Function的實例,那就是函數對象,其余則為普通對象。

那么說到對象,我們從上面可以看出,一個對象是通過構造函數 new 出來的,這其實跟原型和原型鏈有很大的關系,那么原型和原型鏈到底是用來干嘛的呢?

原型

涉及到這兩個概念,我們就必須先來介紹兩個東西: __proto__ 和 prototype ,這兩個變量可以說,在 javascript  這門語言里面隨處可見,我們不管他三七二十一,我們先來看一張表:

Javascript原型和原型鏈的知識點整理

所以,請你先記住以下結論:

  • 只有函數對象有 prototype 屬性,普通對象 沒有這個屬性。

  • 函數對象 和 普通對象 都有 __proto__這個屬性。

  • prototype 和 __proto__都是在創建一個函數或者對象會自動生成的屬性。

接著我們來驗證一下:

function func (){  //func稱為構造函數  } 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 (看見了吧,普通對象真的沒有 prototype 屬性)

所以就驗證了我們剛剛的結論:

  • 只有函數對象有 prototype 屬性,普通對象 沒有這個屬性

  • 函數對象 和 普通對象 都有 __proto__這個屬性。

  • prototype 和 __proto__都是在創建一個函數或者對象會自動生成的屬性。

你看我又重復寫了一遍,我不是為了湊字數,是為了你加深記憶,這對于我們接下來的篇幅很重要。接著我們來看看下面的代碼:

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

所以我們又得出如下結論:

  • 實例的 __proto__屬性主動指向構造的 prototype;

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

這就是prototype 屬性和 __proto__ 屬性的區別與聯系。這可能又有點繞了,來多看幾遍這一節,多背一下我們的結論。我們繼續。

那么問題來了,既然func是一個函數對象,函數對象是有 prototype 屬性的,那么func.prototype.__proto__等于啥呢?

為了解決這個問題,我們來思考一下:

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

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

好,我們知道了,func.prototype 是一個對象,那既然是對象,那 func.prototype 那不就是  Object的實例嗎?那也就是說,func.prototype.__proto__屬性肯定是指向 Object.prototype  咯!好,我們來驗證一下:

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

看見沒有,就是這樣的。那看到這里,我們應該也知道當我們這創建一個構造函數的時候,javascript是如何幫我們自動生成__proto__和prototype屬性的。哈哈沒錯就是這樣:

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

我還專門為你畫了個圖(夠貼心不老鐵):

 Javascript原型和原型鏈的知識點整理

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

hi,看到這里,你是不是有種腦子開了光的感覺。哈哈,所以到現在你應該已經理解原型的概念了,如果你還不理解,那就把上述章節再看一遍。最好拿個紙筆出來跟著畫一畫,順便拿出電腦把示例代碼敲一敲。好,整理一下頭腦,接下來我們來看看什么又是原型鏈。

原型鏈

再介紹這個概念之前,我們先來看如下代碼:

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****//

接下來我們來逐步解析一下:

1.創建了一個構造函數 Person,此時,Person.portotype自動創建,其中包含了 constructor 和  __proto__兩個屬性;

2.給對象 Person.prototype 新增了一個方法 getName;

3.給對象 Person.prototype 新增了一個方法 getDesc;

4.構造函數 Person 新建一個實例: obj(在創建實例的時候,構造函數會自動執行);

5.打印實例 obj :

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

根據上面一節的結論,我們得出:

obj.__proto__ = Person.prototype;

6.執行到第6步時,由于在實例 obj 上面找不到 getName()這個方法,所以它就會自動去通過自身的 __proto__ 繼續向上查找,結果找到了  Person.prototype ,接著它發現,剛好 Person.prototype  上面有getName()方法,于是找到了這個方法,它就停止了尋找。怎么樣,是不是有一種環環相扣的感覺?他們形成一個鏈了,沒錯,這就是原型鏈。

我們得出如下結論:

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

是不是自然而然就理解了。我又給你畫了個圖(請對照著上面?那個圖看):

Javascript原型和原型鏈的知識點整理

接下來我們再來增加一些概念:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 任何內置函數對象本身的 __proto__屬性都指向 Function的原型對象,即: Function.prototype;

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

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

Javascript原型和原型鏈的知識點整理

針對這個圖,我最終給出我們經常看見那個原型鏈的圖:

Javascript原型和原型鏈的知識點整理

好好對比一下,拿出紙和筆畫一畫,根據上面章節的講解,相信你很容易就能明白。

javascript中的類

剛剛我們終于明白什么是 原型 和  原型鏈。下面我們根據上面的概念來講解一下javascript中的類。我們知道,在面向對象的語言中,類可以被實例化多次,這個實例化是指我們可以根據構造函數去獨立復制多個獨立的實例,這些實例之間是獨立的。但是實際上在  javascript  卻不是這樣的,因為它不是這種復制機制。我們不能創建一個類的多個實例,我們只能創建這個類的多個對象,因為他們都是通過原型和原型鏈關聯到同一個對象。所以在  javascript 中 ,類都是通過原型和原型鏈來實現的,它其實是一種委托方式。

new的實現

了解了上面javascript中的類的概念,那我們應該很容易就理解new的過程,其核心無非就是執行原型鏈的鏈接:

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

instanceof的實現

那么學習了原型和原型鏈,instanceof的實現肯定也很簡單了,它也是通過原型和原型鏈來實現的:

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__;      }  }

我就不講解過程了,因為我知道你肯定能看懂,哈哈。

javascript的繼承

我們都知道繼承也是通過原型和原型鏈來實現的,那我在這里介紹兩種常見的繼承方式:

1.組合繼承:

//組合式繼承 //通過call繼承Parent的屬性,并傳入參數 //將Child的原型對象指向Parent的實例,從而繼承Parent的函數  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.寄生組合式繼承:

//寄生組合式繼承 //通過call繼承Parent的屬性,并傳入參數 //通過Object.create()繼承Parent的函數   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       }   })

總結

  1. 若 A 通過 new 創建了 B,則 B.__proto__ = A.prototype;

  2. 執行B.a,若在B中找不到a,則會在B.__proto__中,也就是A.prototype中查找,若A.prototype中仍然沒有,則會繼續向上查找,最終,一定會找到Object.prototype,倘若還找不到,因為Object.prototype.__proto__指向null,因此會返回undefined;

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

感謝各位的閱讀,以上就是“Javascript原型和原型鏈的知識點整理”的內容了,經過本文的學習后,相信大家對Javascript原型和原型鏈的知識點整理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

昌黎县| 日照市| 神农架林区| 福泉市| 华蓥市| 嘉祥县| 彰化市| 杭州市| 哈巴河县| 吉首市| 平乡县| 蒙阴县| 年辖:市辖区| 麻江县| 武清区| 兰溪市| 苏尼特右旗| 大邑县| 平邑县| 资溪县| 海安县| 通州市| 芮城县| 勃利县| 朝阳县| 吴堡县| 夹江县| 嘉兴市| 金塔县| 封丘县| 潼关县| 尤溪县| 新龙县| 海盐县| 保靖县| 深泽县| 沭阳县| 海南省| 富民县| 吉林市| 宣城市|