<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面不面試的,你都得懂原型和原型鏈

          共 4380字,需瀏覽 9分鐘

           ·

          2021-04-06 18:35


          作者:尼克陳

          https://juejin.cn/post/6934498361475072014

          前言

          不要為了面試而去背題,匆匆忙忙的,不僅學不進去,背完了幾天后馬上會忘記。

          image.png

          你可能會說,“沒辦法,這不是為了能找份工作嘛!”。我想說的是,“那你沒開始找工作的時候,咋不好好學習呢。”

          好了,上述扯的這些,意思就是讓大家不要做收藏家,不要把好文收藏了,就放在收藏夾里吃灰!

          下面為大家簡單闡述我對原型和原型鏈的理解,若是覺得有說的不對的地方,還望直接把頁面關閉了,別在我這篇文章上繼續(xù)浪費時間。(逃)


          四個規(guī)則

          我們先來了解下面引用類型的四個規(guī)則:

          1、引用類型,都具有對象特性,即可自由擴展屬性。

          2、引用類型,都有一個隱式原型 __proto__ 屬性,屬性值是一個普通的對象。

          3、引用類型,隱式原型 __proto__ 的屬性值指向它的構造函數(shù)的顯式原型 prototype 屬性值。

          4、當你試圖得到一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那么它會去它的隱式原型 __proto__(也就是它的構造函數(shù)的顯式原型 prototype)中尋找。

          引用類型:Object、Array、Function、Date、RegExp。這里我姑且稱 proto 為隱式原型,沒有官方中文叫法,大家都瞎叫居多。

          下面我們逐一驗證上面幾個規(guī)則,就會慢慢地理解原型和原型鏈。

          規(guī)則一

          引用類型,都具有對象特性,即可自由擴展屬性:

          const obj = {}
          const arr = []
          const fn = function ({}

          obj.a = 1
          arr.a = 1
          fn.a = 1

          console.log(obj.a) // 1
          console.log(arr.a) // 1
          console.log(fn.a) // 1
          復制代碼

          這個規(guī)則應該比較好理解,Date 和 RegExp 也一樣,就不贅述了。

          規(guī)則二

          引用類型,都有一個隱式原型 __proto__ 屬性,屬性值是一個普通的對象:

          const obj = {};
          const arr = [];
          const fn = function({}

          console.log('obj.__proto__', obj.__proto__);
          console.log('arr.__proto__', arr.__proto__);
          console.log('fn.__proto__', fn.__proto__);
          復制代碼

          規(guī)則三

          引用類型,隱式原型 __proto__ 的屬性值指向它的構造函數(shù)的顯式原型 prototype 屬性值:

          const obj = {};
          const arr = [];
          const fn = function({}

          obj.__proto__ == Object.prototype // true
          arr.__proto__ === Array.prototype // true
          fn.__proto__ == Function.prototype // true
          復制代碼

          規(guī)則四

          當你試圖得到一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那么它會去它的隱式原型 __proto__(也就是它的構造函數(shù)的顯式原型 prototype)中尋找:

          const obj = { a:1 }
          obj.toString
          // ? toString() { [native code] }
          復制代碼

          首先, obj 對象并沒有 toString 屬性,之所以能獲取到 toString 屬性,是遵循了第四條規(guī)則,從它的構造函數(shù) Objectprototype 里去獲取。

          一個特例

          我試圖想推翻上面的規(guī)則,看下面這段代碼:

          function Person(name{
            this.name = name
            return this // 其實這行可以不寫,默認返回 this 對象
          }

          var nick = new Person("nick")
          nick.toString
          // ? toString() { [native code] }
          復制代碼

          按理說, nickPerson 構造函數(shù)生成的實例,而 Personprototype 并沒有 toString 方法,那么為什么, nick 能獲取到 toString 方法?

          這里就引出 原型鏈 的概念了, nick 實例先從自身出發(fā)檢討自己,發(fā)現(xiàn)并沒有 toString 方法。找不到,就往上走,找 Person 構造函數(shù)的 prototype 屬性,還是沒找到。構造函數(shù)的 prototype 也是一個對象嘛,那對象的構造函數(shù)是 Object ,所以就找到了 Object.prototype 下的 toString 方法。


          上述尋找的過程就形成了原型鏈的概念,我理解的原型鏈就是這樣一個過程。也不知道哪個人說過一句,JavaScript 里萬物皆對象。從上述情況看來,好像是這么個理。??

          一張圖片

          用圖片描述原型鏈:


          最后一個 null,設計上是為了避免死循環(huán)而設置的, Object.prototype 的隱式原型指向 null

          一個方法

          instanceof 運算符用于測試構造函數(shù)的 prototype 屬性是否出現(xiàn)在對象原型鏈中的任何位置。instanceof 的簡易手寫版,如下所示:

          // 變量R的原型 存在于 變量L的原型鏈上
          function instance_of (L, R{    
            // 驗證如果為基本數(shù)據(jù)類型,就直接返回 false
            const baseType = ['string''number''boolean''undefined''symbol']
            if(baseType.includes(typeof(L))) { return false }

            let RP = R.prototype;  // 取 R 的顯示原型
            L = L.__proto__; // 取 L 的隱式原型
            while (true) {
              if (L === null) { // 找到最頂層
                return false;
              }
              if (L === RP) { // 嚴格相等
                return true;
              }
              L = L.__proto__;  // 沒找到繼續(xù)向上一層原型鏈查找
            }
          }
          復制代碼

          我們再來看下面這段代碼:

          function Foo(name{
            this.name = name;
          }
          var f = new Foo('nick')

          instanceof Foo // true
          instanceof Object // true
          復制代碼

          上述代碼判斷流程大致如下:

          1、 f instanceof Foof 的隱式原型 __proto__Foo.prototype ,是相等的,所以返回 true

          2、 f instanceof Objectf 的隱式原型 __proto__ ,和 Object.prototype 不等,所以繼續(xù)往上走。f 的隱式原型 __proto__ 指向 Foo.prototype ,所以繼續(xù)用 Foo.prototype.__proto__ 去對比 Object.prototype ,這會兒就相等了,因為 Foo.prototype 就是一個普通的對象。

          再一次驗證萬物皆對象。。。。

          總結

          通過四個特性、一個例子、一張圖片、一個方法,大家應該對原型和原型鏈的關系有了大概的認知。我的認知就是,原型鏈就是一個過程,原型是原型鏈這個過程中的一個單位,貫穿整個原型鏈。就好像你要是看完了不點個贊,我可以順著網(wǎng)線找到你。

          點贊和在看就是最大的支持??

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91操屄视频 | 女人高潮免费视频 | 久草 超碰 | 国产精品久久久久久高潮 | 成人黄片在线免费观看 |