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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                >[info] ## Js 中的原型繼承 ~~~ 1.自定義函數時(箭頭函數除外)也會默認生成,生成的顯式原型對象只有一個屬性 constructor , 該屬性指向函數自身。通常配合 new 關鍵字一起使用 2.這里解釋一下'prototype(顯式原型)'、"__proto__(隱式原型)" 2.1.'prototype' 是函數的屬性,指向該構造函數的原型對象,首先函數也是一個對象,因此函數也可以定義屬性 像第一條說的除了箭頭函數,其他的函數都會默認生成一個顯示原型對象,也就是key 為'prototype',并且對 應的value 是一個對象,這個對象默認包含一個constructor 屬性指向的是函數自身 2.2.'__proto__'是對象的屬性,指向該對象的構造函數的原型對象,這個是瀏覽器廠商提出的下面有具體解釋 3.'prototype'放公用屬性方法,'__proto__'告訴你可以去那里找公用屬性和方法 ~~~ * 2.1 說明 ~~~ function test(){} Object.getOwnPropertyNames(test) // 打印結果 ["length", "name", "arguments", "caller", "prototype"] ~~~ ~~~ function fn() {} fn.prototype.constructor === fn // true ~~~ * 一下內容來源 javasprict 設計模式與開發實踐 ~~~ 1.js 是通過原型鏈相互繼承的,因此需要遵守以下規則: 1.1 所有的數據都是對象 1.2 要得到一個對象,不是通過實例化類,而是找到一個對象作為原型并克隆他 1.3 對象會記住它的原型 1.4 如果對象無法響應某個請求,它會把這個請求委托給它自己的原型 ~~~ >[danger] ##### 解釋 -- 所有的數據都是對象 ~~~ 1.在js 中這句話不是完全對的,除了undefined ,所有數據都是對象 ~~~ >[danger] ##### 解釋 -- 要得到一個對象,不是通過實例化類,而是找到一個對象作為原型并克隆他 ~~~ 1.下面的案例當使用new 的時候會調用,此時的函數不是普通函數,而是變成了構造 器,先克隆Object.prototype對象,在進行其他操作 2.可以利用getPrototypeOf 來看當前實例對象的原型 ~~~ ~~~ function Person(name) { this.name = name } Person.prototype.getName=function(){ return this.name } var a = new Person('sven') console.log(Object.getPrototypeOf(a) === Person.prototype) // true ~~~ >[danger] ##### 解釋 -- 對象會記住它的原型 ~~~ 1.原型就是對象的屬性,包括被稱為隱式原型的 proto 屬性和被稱為顯式原型的 prototype 屬性 2.瀏覽器廠商為我們增加'__proto__' 屬性,通過這個屬性我們可以看到當前對象繼承 的原型舉個例子 var a = new Object() console.log(a.__proto__ === Object.prototype) // true 對象指向了他的原型 3.通過下面代碼弄清一個概念,首先創建了一個'DoSomething',并且給'DoSomething'的原型鏈賦值屬性'name', 打印他的原型鏈,發現name 和構造函數'constructor' 屬于'DoSomething'自己的,通過 '__proto__'可以看到當前 'DoSomething'繼承的原型'Object',通過new創建的'doSomething' 對象同理 ~~~ * 解釋第一條 ~~~ 1.當創建對象 a 時,a 的隱式原型會指向構造函數 Object() 的顯式原型 ~~~ ~~~ var a = {} a.__proto__ === Object.prototype // true var b= new Object() b.__proto__ === a.__proto__ // true ~~~ * 通過其他例子來理解 ~~~ function DoSomething(){} console.log( DoSomething.prototype ); DoSomething.prototype.name = 'wang' // { // name: "wang", ------------> name 屬性是DoSomething自己的所以不是從他的copy原型來的,因此不再__proto__ // constructor: ? DoSomething(), // __proto__: { -----------------> 這里的原型鏈指向的是Object,這證明最開始說的'Object'就是所有對象的原型' // constructor: ? Object(), // hasOwnProperty: ? hasOwnProperty(), // isPrototypeOf: ? isPrototypeOf(), // propertyIsEnumerable: ? propertyIsEnumerable(), // toLocaleString: ? toLocaleString(), // toString: ? toString(), // valueOf: ? valueOf() // } // } const doSomething = new DoSomething() doSomething.age = 17 console.log( doSomething) // { // age: 17, ---------》 age 屬性是doSomething 的因此不再__proto__ // __proto__: { ---------》doSomething 是從DoSomething克隆來的因此一層原型鏈指向是DoSomething // name: "wang", // constructor: ? DoSomething(), // __proto__: { -----------------》DoSomething 是從Object 來的因此第二層是在Object // constructor: ? Object(), // hasOwnProperty: ? hasOwnProperty(), // isPrototypeOf: ? isPrototypeOf(), // propertyIsEnumerable: ? propertyIsEnumerable(), // toLocaleString: ? toLocaleString(), // toString: ? toString(), // valueOf: ? valueOf() // } // } // } ~~~ >[danger] ##### 解釋 -- 如果對象無法響應某個請求,它會把這個請求委托給它自己的原型 ~~~ 1.雖然JavaScript的對象最初都是由Object.prototype對象克隆而來的,但對象構造器的原型 并不僅限于Object.prototype上,而是可以動態指向其他對象。這樣一來,當對象a需要借用 對象b的能力時,可以有選擇性地把對象a的構造器的原型指向對象b,從而達到繼承的效果。 下面的代碼原型繼承方式 1.1.首先,嘗試遍歷對象a中的所有屬性,但沒有找到name這個屬性。 1.2.查找name屬性的這個請求被委托給對象a的構造器的原型,它被a.__proto__ 記錄著并且指向A.prototype,而A.prototype被設置為對象obj。 1.3.在對象obj中找到了name屬性,并返回它的值。 ~~~ ~~~ var obj = { name: 'sven' }; var A = function(){}; A.prototype = obj; var a = new A(); console.log( a.name ); ~~~ ~~~ 1.當我們期望得到一個'類'繼承自另外一個'類'的效果時,往往會用下面的代碼來模擬實現: 1.1 首先,嘗試遍歷對象b中的所有屬性,但沒有找到name這個屬性。 1.2 查找name屬性的請求被委托給對象b的構造器的原型,它被b.__proto__ 記錄著并且 指向B.prototype,而B.prototype被設置為一個通過new A()創建出來的對象。 1.3 在該對象中依然沒有找到name屬性,于是請求被繼續委托給這個對象構造器的原型A.prototype。 1.4在A.prototype中找到了name屬性,并返回它的值。 ~~~ ~~~ var A = function(){}; A.prototype = { name: 'sven' }; var B = function(){}; B.prototype = new A(); var b = new B(); console.log( b.name ); ~~~ >[danger] ##### Object.create -- 克隆原型 [MDN -- Object.create](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create) ~~~ 1.我們之前說了'js是基于原型'創建對象,只要我們能復制一個對象創建一個新的變向就相當于創建了一個對象, 這里js也提供了一個方法'Object.create' ~~~ * 簡單理解 ~~~ 1.ECMAScript 5 中引入了一個新方法:Object.create()。可以調用這個方法來創建一個新對象。新對象的原型就是調 用 create 方法時傳入的第一個參數 2.相比js 本身'{}'創建對象是一次性,改變了后續的引用都會變,相比以前通過構造函數方式也好,通過閉包的 方式也好,無非都是想讓對象可以在同一復制出來多個,現在'Object.create' 就完全可以做到了 ~~~ ~~~ function Person( name ){ this.name = name; }; Person.prototype.getName = function(){ return this.name; }; // 這里讓o2對象的原型鏈指向了Person,并且給o2對象自己添加了個屬性p /* 下面的寫法等同于 const o2 = new Object() o2.__proto__ = Person.prototype o2.p = 42 所以o2只是繼承了Person.prototype原型鏈但是沒有基礎他的name屬性 因此o2是沒有name屬性的 */ o2 = Object.create(Person.prototype, { p: { value: 42, writable: true, enumerable: true, configurable: true } }); // 打印結果如圖一 console.log(o2) const per = new Person() o3 = Object.create(per, { p: { value: 42, writable: true, enumerable: true, configurable: true } }); // 打印結果如圖一 console.log(o3) ~~~ * 圖一 ![](https://img.kancloud.cn/6c/c1/6cc1ff3ac53ae9eaa206e12d5cb5a368_207x59.png) >[info] ## 圖形化理解 ![](https://img.kancloud.cn/3f/83/3f839d02f45e7da804c2026c11c0353e_486x251.png) >[info] ## 參考 [參考文章推薦](https://juejin.im/post/5d622f14f265da03a1486408#heading-0) [參考文章推薦](https://juejin.im/post/5cc99fdfe51d453b440236c3) [具有參考的文章](https://www.zhihu.com/question/34183746) [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>

                              哎呀哎呀视频在线观看