<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之旅 廣告
                ## **原型** 歸根結底,原型其實也是一個對象,對象也是 `ECMAScript` 中最基本的概念。 那么我們來看一下對象這個概念,舉一個基本 `Object` 的例子,首先我們要清楚,一個 `Object` 的原型是一個內部的 `[[prototype]]` 屬性的引用。 不過我們一般會使用 `__proto__` 來來代替 `[[prototype]]`,不過這只是某些瀏覽器給出的便捷訪問的方式,所以并非標準,但不妨礙我們了解原型。 *` Object`* ``` var foo = { x: 10, y: 20 } foo.__proto__ === Object.prototype // true ``` 我們可以看到 `foo` 是一個普通對象,谷歌可以通過 `__proto__` 來訪問對象原型。 ## **原型鏈** 原型對象是一個對象,并且有可能有自己的原型,如果一個原型對象的原型不是 `null`,就有可能還有自己的原型,這就像鏈條一樣,構成了原型鏈。 > A prototype chain is a finite chain of objects which is used to implemented inheritance and shared properties. 原型鏈是一個由對象組成的有限對象鏈由于實現繼承和共享屬性。 想象一個這種情況,2個對象,大部分內容都一樣,只有一小部分不一樣,很明顯,在一個好的設計模式中,我們會需要重用那部分相同的,而不是在每個對象中重復定義那些相同的方法或者屬性。在基于類 `[class-based]` 的系統中,這些重用部分被稱為類的繼承 – 相同的部分放入 `class A`,然后 `class B` 和 `class C` 從A繼承,并且可以聲明擁有各自的獨特的東西。 `ECMAScript` 沒有類的概念。但是,重用 `[reuse]` 這個理念沒什么不同(某些方面,甚至比 `[class-based]` 更加靈活),可以由 `prototype chain` 原型鏈來實現。這種繼承被叫做原型繼承。 ``` var a = { x: 10, calculate: function (z) { return this.x + this.y + z } } var b = { y: 20, __proto__: a } var c = { y: 30, __proto__: a } // 上面對象表達式中直接聲明了__proto__屬性為a, 所以可以使用原型a上面的方法 b.calculate(30) // 10 + 20 + 30 = 60 c.calculate(40) // 10 + 30 + 40 = 80 ``` 這種繼承方式很直觀,`b` 和 `c` 都可以訪問他們的 `__proto__` 原型對象里面的屬性。 所以原型鏈有下列關系: ``` // 函數對象實例, 例如: var Foo = function () {} Foo.__proto__ === Function.prototype // 普通對象實例, 例如: var object = {} object.__proto__ === Object.prototype // 因為所有的原型鏈盡頭都是Object.prototype -> null // 所以Function.prototype 也有自己的原型 Function.prototype.__proto__ === Object.prototype Object.prototype.__proto__ === null // 所以總結為: Object.__proto__ === Function.prototype Function.prototype.__proto__ === Object.prototype Object.prototype.__proto__ === null ``` 由上可知:***函數對象實例***比 ***普通對象實例*** 要多一層原型鏈,而且只有 ***函數*** 才有 `prototype` 屬性,與之相對應的實例屬性是 `__proto__`,這就是默認的對象原型和原型鏈。 ## **構造函數** 但是通常我們不會用上面那個方式實現繼承,我們會封裝構造函數來創建新的實例: ``` // 構造函數 function Foo(y) { // 構造函數將會以特定模式創建對象:被創建的對象都會有"y"屬性 this.y = y } // Foo.prototype 存放了新建對象的原型引用 // 所以這里定義繼承和共享的屬性或方法 Foo.prototype = { x: 10, calculate: function (z) { return this.x + this.y + z } } // this.y = y var b = new Foo(20) var c = new Foo(30) // 調用繼承方法 b.calculate(30) // 10 + 20 + 30 = 60 c.calculate(40) // 10 + 30 + 40 = 80 // 實例的 __proto__ 屬性 === 構造函數的 prototype 屬性 b.__proto__ === Foo.prototype // true c.__proto__ === Foo.prototype // true // Foo.prototype 自動創建了一個特殊的屬性 constructor // 這個屬性等于構造函數本身 b.constructor === Foo // true c.constructor === Foo // true Foo.prototype.constructor === Foo // true // 下面證明實例繼承來的方法和原型上的方法是同一個 b.calculate === b.__proto__.calculate // true b.__proto__.calculate === Foo.prototype.calculate // true ``` ![](https://box.kancloud.cn/a504f06150f594c7af52a7ed2eda45ec_627x392.png) 因為 `__proto__` 并非標準,`Foo.prototype` 才是顯式的屬性,也就是 `b` 和 `c` 的 `__proto__` 屬性。 每個對象都有原型,表現出來的形式是構造函數的 `prototype` 屬性,所以我們一般操作原型的時候都會使用構造函數。 可以這么說,所有的對象都有原型,根據不同瀏覽器訪問的方式可能會不同,拿谷歌為例,可以訪問對象的 `__proto__` 屬性來訪問原型,`arguments` 是一個類數組,不是數組卻是對象,所以: ``` function Foo () { console.log(arguments.__proto__ === Object.prototype) // true console.log(Object.__proto__ === Function.prototype) // true } ```
                  <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>

                              哎呀哎呀视频在线观看