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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] >[success] # 更強大的原型 原型是在`JS`中進行繼承的基礎, `ES6` 則在繼續讓原型更強大。早期的`JS`版本對原型的使用 有嚴重限制,然而隨著語言的成熟,開發者也越來越熟悉原型的工作機制,因此他們明顯希 望能對原型有更多控制權,并能更方便地使用它。于是 ES6 就給原型引入了一些改進。 >[success] ## ES6新增對象方法 ~~~ 首先介紹一下,下面幾個對象的方法: ~~~ <br/> >[success] ### Object.setPrototypeOf() ~~~ 'Object.setPrototypeOf()' 方法'設置一個指定的對象的原型'(即, 內部[[Prototype]]屬性) 到另一個對象或 null,和'Object.create()'類似,兩者的區別:'Object.create()'是新建一個對象 可以為這個對象指定另一個對象的'原型','Object.setPrototypeOf()' 是改變源對象,為其指定另一個 對象的'原型' 語法: Object.setPrototypeOf(obj, prototype) 參數: 1. 'obj':要設置其原型的對象。 2. 'prototype' : 該對象的新原型(一個對象 或 null) ~~~ 1. 簡單例子 ~~~ function fun1 () { } // 下面的操作,相當于在這個原型鏈里面新增了一些方法 // fun1.prototype.age = '18'; let obj1 = new fun1() Object.setPrototypeOf(obj1, { age: '18' }) console.log(obj1) ~~~ <br/> >[success] ### Object.defineProperty() ~~~ 'Object.defineProperty()'的作用就是直接在一個對象上'定義一個新屬性',或者'修改一個已經存在的屬性' 語法: Object.defineProperty(obj, prop, desc) 參數: 1. 'obj' : 需要定義屬性的當前對象 2. 'prop' :當前需要定義的屬性名 3. 'desc': 屬性描述符 ~~~ 1. 添加(修改)屬性 ~~~ var o = {}; // 創建一個新對象 // 在對象中添加一個屬性與數據描述符的示例 Object.defineProperty(o, "a", { value : 37, writable : true, enumerable : true, configurable : true }); ~~~ <br/> >[success] ### Object.defineProperties() 對象新增(修改)屬性,返回對象 ~~~ 'Object.defineProperties()'方法直接在一個對象上定義'新的屬性或修改現有屬性',并'返回該對象'。 ~~~ ~~~ 語法:Object.defineProperties(obj, props) 參數: 'obj' 需要定義屬性的當前對象 'prop' 當前需要定義的屬性名 ~~~ <br/> >[success] ### Object.getOwnPropertyDescriptor 獲取對象屬性的屬性描述符 ~~~ let obj = { aa:'111', bb:'222' } console.log(Object.getOwnPropertyDescriptor(obj,'aa')) // {"aa":{"value":"111","writable":true,"enumerable":true,"configurable":true}} 語法:Object.getOwnPropertyDescriptor(obj, props) 參數: 'obj' 要在其中查找屬性的對象 'prop' Symbol要檢索其描述的名稱或屬性。 ~~~ <br/> >[success] ### Object.getOwnPropertyDescriptors 獲取對象全部屬性的屬性描述符 ~~~ let obj = { aa:'111', bb:'222' } console.log(Object.getOwnPropertyDescriptors(obj,'aa')) // {"aa":{"value":"111","writable":true,"enumerable":true,"configurable":true},"bb":{"value":"222","writable":true,"enumerable":true,"configurable":true}} 語法:Object.getOwnPropertyDescriptors(obj) 參數: 'obj' 要查找屬性的對象 ~~~ <br/> >[success] ## 修改原型 ~~~ let person = { getGreeting() { return "Hello" } } let dog = { getGreeting() { return "Woof" } } // 原型為 person let friend = Object.create(person) console.log(friend.getGreeting()) // "Hello" console.log(Object.getPrototypeOf(friend) === person) // true // 將原型設置為 dog Object.setPrototypeOf(friend, dog) console.log(friend.getGreeting()) // "Woof" console.log(Object.getPrototypeOf(friend) === dog) // true ~~~ <br/> >[success] ## 使用 super 引用的簡單原型訪問 [參考文章:js中的super的使用](http://www.fly63.com/article/detial/4207) ~~~ 1. 'this關鍵詞'指向函'數所在的當前對象' 2. 'super'指向的是'當前對象的原型對象' ~~~ <br/> >[success] ### ES5原型訪問 ~~~ // 原型對象1 const person = { name: '小明1', test(){ console.log('我是原型的方法1') } } // 基礎原型對象 const man = { name: '小明', test(){ console.log('我是自身的方法') }, getProtoAttr() { // 調用原型屬性 return Object.getPrototypeOf(this).name }, getProtoFun(){ // 調用原型方法 return Object.getPrototypeOf(this).test.call(this) } } // 修改man對象的原型對象為person Object.setPrototypeOf(man, person) // 調用自身的私有屬性以及方法 console.log(man.name) // 小明 man.test() // 我是自身的方法 // 調用原型鏈的屬性和方法 console.log(man.getProtoAttr()) // 小明1 man.getProtoFun() // 我是原型的方法 ~~~ <br/> >[success] ### ES6原型訪問 ~~~ // 原型對象1 const person = { name: '小明1', test(){ console.log('我是原型的方法1') } } // 基礎原型對象 const man = { name: '小明', test(){ console.log('我是自身的方法') }, getProtoAttr() { // 調用原型屬性 return super.name // 注意這里 }, getProtoFun(){ // 調用原型方法 return super.test() // 注意這里 } } // 修改man對象的原型對象為person Object.setPrototypeOf(man, person) // 調用自身的私有屬性以及方法 console.log(man.name) // 小明 man.test() // 我是自身的方法 // 調用原型鏈的屬性和方法 console.log(man.getProtoAttr()) // 小明1 man.getProtoFun() // 我是原型的方法 ~~~ <br/> >[success] ### super中的this指向(易混淆) 1. super.name 指向的是原型對象 person 中的 name ,但是綁定的 this 還是當前的 man 對象。 ~~~ '屬性重名': 自身'私有屬性'和原型鏈屬性'重名'時'super'先調用'自身私有屬性',如果自身沒有這個屬性,'super'會自動去'原型鏈'找這個屬性并且'調用'。 '方法重名','super'只會調用'原型鏈方法'不會調用本地的方法 const person = { age:'20多了', name(){ return this.age } } const man = { age:'18歲了', sayName(){ return super.name() } } // 為man對象設置原型對象 Object.setPrototypeOf( man, person ) // 調用原型鏈方法 console.log( man.sayName() ) // 18歲了 ~~~ 2. Object.getPrototypeOf(this).name 指向的是 person 的 name,綁定的 this 也是 person ~~~ const person = { age: '20多了', name() { return this.age } } const man = { age: '18歲了', sayName() { return Object.getPrototypeOf(this).name() } } // 為man對象設置原型對象 Object.setPrototypeOf(man, person) // 調用原型鏈方法 console.log(man.sayName()) //20多了 ~~~ 3.Object.getPrototypeOf(this).name.call(this)指向的是person的name,不過通過call改變了函數的執行上下文,所以this指向的還是man ~~~ const person = { age: '20多了', name() { return this.age } } const man = { age: '18歲了', sayName() { return Object.getPrototypeOf(this).name.call(this) } } // 為man對象設置原型對象 Object.setPrototypeOf(man, person) // 調用原型鏈方法 console.log(man.sayName()) //18歲了 ~~~ <br/> >[success] ### Class中的super 1. Class中的super(),它在這里表示父類的構造函數,用來新建父類的this對象 ,super()相當于Parent.prototype.constructor.call(this) ~~~ // 父類 class Demo { constructor(x, y) { this.x = x this.y = y } customSplit() { return [...this.y] } } // 子類繼承父類 class Demo2 extends Demo { constructor(x, y) { // 如果不寫constructor,js會自動生成一個空的constructor super(x, y) } customSplit() { return [...this.x] } task1() { // 調用父類(原型鏈)方法 return super.customSplit() } task2() { // 調用自身方法 return this.customSplit() } } let d = new Demo2('hello', 'world') console.log(d.task1()) //["w", "o", "r", "l", "d"] console.log(d.task2()) //["h", "e", "l", "l", "o"] ~~~ 2. 子類沒有自己的this對象,而是繼承父親的this對象,然后進行加工。如果不調用super,子類就得不到this對象 ~~~ class Demo2 extends Demo { constructor(x, y) { this.x = x //this is not defined } } ~~~ ES5的繼承,實質上是先創造子類的實例對象this,然后再將父類的方法添加到this上(Parent.call(this)). ES6的繼承,需要先創建父類的this,子類調用super繼承父類的this對象,然后再加工。 如果子類沒有創建 constructor ,這個方法會被默認添加: ~~~ // 創建父類 class Demo{ constructor(x) { this.x = x; } } // 繼承父類 class Demo2 extends Demo{} // 實例化對象 let d = new Demo2('hello'); d.x //hello ~~~ 3. super 在靜態方法之中指向父類,在普通方法之中指向父類的原型對象。 可以理解成,沒有實例化對象時候,使用靜態的方法只能引靜態的方法,實例化后原型的方法可以使用,并且原型方法權重高所以就引用了原型的方法 ~~~ // 父類 class Parent { // 靜態方法 static myMethod(msg) { console.log('static', msg) } myMethod(msg) { console.log('instance', msg) } } // 子類繼承父類 class Child extends Parent { // 靜態方法 static myMethod(msg) { super.myMethod(msg) } myMethod(msg) { super.myMethod(msg) } } // 直接引用靜態方法 Child.myMethod(1) // static 1 //?實例化子類對象 let child = new Child() child.myMethod(2) // instance 2 ~~~ <br/> >[warning] ### super 使用時需注意 ~~~ 'super'只可以在'簡寫方法'內使用,在'非簡寫'的情況下使用會報錯 ~~~ ~~~ let man= { test: function () { // 語法錯誤 return super.test() } } ~~~
                  <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>

                              哎呀哎呀视频在线观看