<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] >[success] # js --prototype、__proto__與constructor 1. 了解js 對象必須要知道三個屬性**prototype、__proto__與constructor**,在ES標準定義中`__proto__`其實是暴露了通過它訪問的對象的內部 2. 關于`[[Prototype]]` ( `__proto__` )執行過程 2.1. 當我們通過引用對象的屬性**key**來獲取一個**value**時,它會觸發 `[[Get]]`的操作 2.2. 這個操作會首先檢查該對象是否有**對應的屬性**,如果有的話就使用它 2.3. 如果對象中沒有改屬性,那么會訪問對象`[[prototype]]`(`__proto__`)內置屬性指向的對象上的屬性 3. **prototype** 屬性是**函數**所獨有的, 雖然函數也是對象,但是其他對象是不具備**prototype** 屬性`[[Prototype]]`(`__proto__`)和`constructor` 4. 對象具有`[[Prototype]]` ( `__proto__`) 屬性,當對象去掉`constructor`屬性時候,它會觸發 `[[Get]]`的操作發現自身沒有然后會去`[[Prototype]]`中去找到`constructor` 5. 雖然自定義函數時會默認生成顯式原型對象(prototype)但是(**箭頭函數除外**) * **總結** 對象所具備的屬性`[[Prototype]]` ( `__proto__`)和`constructor`,函數也是特殊的對象因此也具有這些屬性,但是**prototype**是函數所獨有屬性 ~~~ // 對象打三個屬性 const aObj = {} console.log(aObj .__proto__) // 有值 console.log(aObj .constructor) // 有值 console.log(aObj .prototype) // undefined // 方法打印三個屬性 function aFun(){} undefined console.log(aFun.__proto__) // 有值 console.log(aFun.constructor) // 有值 console.log(aFun.prototype) // 有值 ~~~ >[danger] ##### 函數是特殊的對象,通過getOwnPropertyNames查看身上的屬性 ~~~ function test(){} Object.getOwnPropertyNames(test) // 打印結果 ["length", "name", "arguments", "caller", "prototype"] ~~~ >[danger] ##### es6 之后獲取隱式\_\_proto\_\_ 1. 在之前瀏覽器廠商么為了可以讓用戶獲取\_\_proto\_\_(隱式原型鏈)上的值,自定義了給瀏覽器使用,不是標準的屬性 \_\_proto\_\_,隨著后續js升級MDN對這個這里的描述該屬性屬于**廢棄屬性** 2. 新版開始定義是`__proto__`暴露了通過它訪問的對象的內部`[[Prototype]]`,也就是說新版開始是要控制內部`[[Prototype]]`,需要使用新的api 2.1. **Object.getPrototypeOf/Reflect.getPrototypeOf** 獲取隱式原型鏈 2.2. **Object.setPrototypeOf/Reflect.setPrototypeOf** 賦值隱式原型鏈,盡管如此,設置對象的[[Prototype]]是一個緩慢的操作,如果性能是一個問題,應該避免去進行賦值操作 [mdn 描述鏈接](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto) >[danger] ##### prototype -- 原型對象 1. **prototype** -- 該屬性的值是一個對象,因為是對象所以它也具有`[[Prototype]]`(`__proto__`)和`constructor` ~~~ function P(){} console.log(P.prototype) ~~~ ![](https://img.kancloud.cn/c0/71/c071411410c09363d344df563b91f9f9_266x80.png)+ >[info] ## 三者的關系 在探索三者關系前要清楚**new** 創建一個對象時候所做的事 1. 在內存中創建一個新的對象(空對象) 2. 這個對象內部的\[\[prototype\]\]屬性會被賦值為該構造函數的prototype屬性 ~~~ function A() {} A.prototype.getName = function () { return 'name' } /** * 創建步驟 * 1. const a = {} // 創建了一個空對象 * 2. a.__proto__ = A.prototype // 隱式原型鏈賦值為該構造函數的prototype屬性 * 也可以寫成 * Object.setPrototypeOf(a,A.prototype) */ const a = new A() ~~~ 因此我們可以將對象共享屬性都放到構造函數的原型鏈上**prototype**,由構造函數創建出來的所有對象, 他們的隱式構造函數\[\[Prototype\]\]都會指向構造函數顯示原型鏈**prototype**達到共享這些屬性 當對象在屬性時候會先在自己身上查找, 沒有找到就會去自己隱式原型上找\[\[Prototype\]\] >[danger] ##### \[\[prototype\]\] 和 prototype關系 首先確定是**構造函數** 通過**new**創建了對象,對象的隱式原型鏈\[\[prototype\]\] 指向了構造函數的**prototype**,因此可以說**對象的隱式原型鏈等于構造函數的prototype** * 通過下面案例可以看出'a2' 和'a1' 共享了getName方法 ~~~ function A(name){ this.name = name } A.prototype.getName = function(){ return this.name } ? (){ return this.name } const a1 = new A('a1') const a2 = new A('a2') ~~~ ~~~ function A() {} A.prototype.getName = function () { return 'name' } const a = new A() console.log(Object.getPrototypeOf(a) === A.prototype) // true ~~~ ![](https://img.kancloud.cn/9a/30/9a3046cf755ac0fb296b0263c067ef76_410x264.png) >[danger] ##### prototype 和 constructor關系 1. prototype 是對象因此它 具有**constructor** 函數, prototype 上**constructor** 屬性指向是所在函數(即構造函數) ~~~ function A() {} console.log(A.prototype.constructor === A) // true ~~~ 2.'prototype'同樣擁有自己的 隱式原型對象[[prototype]] ![](https://img.kancloud.cn/62/15/6215b025ed0fed1d660e7044eaa57a84_621x217.png) >[danger] ##### 三者關系 * \[\[prototype\]\] 指向創建它的構造函數的原型鏈**prototype**,**prototype**作為對象具有**constructor** 屬性,**constructor** 又指向當前構造函數,因此\[\[prototype\]\] 上也有**constructor** 屬性也向當前構造函數 * 由于對象去調用自身不存在的屬性時候,會去隱式原型鏈上找,因此對象可以直接調用**constructor**屬性 ~~~ function Person() {} var PersonPrototype = Person.prototype console.log(PersonPrototype.constructor === Person) // true var p = new Person() console.log(p.__proto__.constructor === Person) // true console.log(p.constructor === Person) // true console.log(p.constructor.name === Person.name) // true ~~~ >[danger] ##### 不要去做的事 -- 重寫原型對象 每創建一個函數, 就會同時創建它的prototype對象, 這個對象也會自動獲取constructor屬性,但重新賦值一個對象相當于丟失了指向自身constructor屬性,而constructor屬性還變成當前賦值對象的 ~~~ function Person() { } console.log(Person.prototype) // 直接賦值一個新的原型對象 Person.prototype = { message: "Hello Person", info: { name: "哈哈哈", age: 30 }, running: function() {}, eating: function() {}, // constructor: Person } // 非要覆蓋 可以這么寫 Object.defineProperty(Person.prototype, "constructor", { enumerable: false, configurable: true, writable: true, value: Person }) ~~~ >[danger] ##### 小補充對象創建過程 [參考](http://www.hmoore.net/cyyspring/more/2226424) >[info] ## 文章參考 [幫你徹底搞懂JS中的prototype、__proto__與constructor(圖解)](https://blog.csdn.net/cc18868876837/article/details/81211729) [03 | JavaScript 如何實現繼承?](https://kaiwu.lagou.com/course/courseInfo.htm?courseId=822#/detail/pc?id=7199) [# 繼承與原型鏈mdn](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看