<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國際加速解決方案。 廣告
                繼承模式 # 原型鏈 new創建的對象 通過__proto__指向 其原型對象; 原型對象也具有對象固有的普遍特征,又指向原型對象的原型對象,以此類推,形成一條鏈條。 ``` function Shape(){ this.name = 'shape'; this.toString = function () { return this.name; } } function TwoDShape(){ this.name = '2D shape'; } function Triangle(side, height){ this.name = 'Triangle'; this.side = side; this.height = height; this.getArea = function(){ return this.side * this.height/2; } } Shape.prototype // {constructor: ?} constructor: ? Shape() __proto__: Object Shape.constructor // ? Function() { [native code] } TwoDShape.prototype // {constructor: ?} constructor:? TwoDShape() __proto__:Object TwoDShape.constructor // ? Function() { [native code] } Triangle.prototype // {constructor: ?} constructor:? Triangle(side, height) __proto__:Object Triangle.constructor // ? Function() { [native code] } // 另建一個新實體,用它覆蓋對象的原型 TwoDShape.prototype = new Shape(); Triangle.prototype = new TwoDShape(); Shape.prototype // {constructor: ?} Shape.constructor // ? Function() { [native code] } TwoDShape.prototype // Shape?{name: "shape", toString: ?} TwoDShape.constructor // ? Function() { [native code] } Triangle.prototype // Shape?{name: "2D shape"} Triangle.constructor // ? Function() { [native code] } new TwoDShape().constructor new Triangle().constructor new Shape().constructor // ? Shape(){ // this.name = 'shape'; // this.toString = function () { // return this.name; // } // } // 將對象的prototype重寫,有可能影響對象的contructor屬性,記得重置! TwoDShape.prototype.constructor = TwoDShape; Triangle.prototype.constructor = Triangle; var my = new Triangle(5, 10); my.getArea(); my.toString(); my.constructor; my instanceof Triangle; my instanceof TwoDShape; my instanceof Shape; my instanceof Array; Triangle.prototype.isPrototypeOf(my) TwoDShape.prototype.isPrototypeOf(my) Shape.prototype.isPrototypeOf(my) String.prototype.isPrototypeOf(my) ``` ## 將共享屬性遷移到原型中去 ``` function Shape(){ this.name = 'shape'; } ``` 用構造器創建對象時,每個實體都會有一個全新的屬性,擁有獨立的存儲空間; ``` function Shape(){} Shape.prototype.name = 'shape'; ``` 對于不可變屬性(共享屬性)及共享方法來說,這樣處理更有效率。 ``` function Shape(){} Shape.prototype.name='shape'; // "shape" Shape.prototype.constructor= function(){return this.name;} // ? (){return this.name;} function TwoDShape(){} TwoDShape.prototype.name = '2D shape'; // 先擴展 // "2D shape" TwoDShape.prototype = new Shape(); // 后繼承 // Shape.constructor?{} TwoDShape.prototype.constructor = TwoDShape; // ? TwoDShape(){} TwoDShape.prototype.name; // "shape" // 被覆蓋 ``` ??通常**先**完成相關的**繼承**關系構建,**再**對原型對象進行**擴展**! ``` function Shape(){}; Shape.prototype.name = 'shape'; Shape.prototype.toString = function(){return this.name;}; function TwoDShape(){}; // 先繼承 TwoDShape.prototype = new Shape(); TwoDShape.prototype.constructor = TwoDShape; // 后擴展 TwoDShape.prototype.name = '2D shape'; function Triangle(side, height){ this.side = side; this.height = height; } Triangle.prototype = new TwoDShape(); Triangle.prototype.constructor = Triangle; Triangle.prototype.name = 'triangle'; Triangle.prototype.getArea = function(){ return this.side * this.height / 2; } var my = new Triangle(5, 10); my.getArea(); // 25 my.toString(); // triangle my.hasOwnProperty('name'); // false my.hasOwnProperty('height'); // true TwoDShape.prototype.isPrototypeOf(my); // true my instanceof Shape; // true ``` # 只繼承于原型 處于效率方面的考慮,應**盡可能將可重用的屬性和方法添加到原型中** 原型中的代碼都是可重用的 改善效率的做法: * 不要單獨為繼承關系創建新對象 * 盡量減少運行時方法搜索 ``` ... TwoDShape.prototype = Shape.prototype; ... Triangle.prototype = TwoDShape.prototype; ... my.toString(); // 此時查找次數相較之前的方式有變化嗎? ``` toString方法只會查找兩次,自身一次,Shape.prototype一次就可以了。 采用了引用傳遞,都指向Shape.prototype ?副作用:子對象對原型的修改,會影響父對象及所有繼承關系。如: `Triangle.prototype.name = 'triangle';` 相當于:`Shape.prototype.name = 'triangle';` ## 臨時構造器——new F() 空函數f(),中介作用,打破所有屬性都指向一個相同的對象。 ``` function Shape(){}; Shape.prototype.name = 'shape'; Shape.prototype.toString = function(){return this.name;}; function TwoDShape(){}; var F = function(){}; F.prototype = Shape.prototype; TwoDShape.prototype = new F(); TwoDShape.prototype.constructor = TwoDShape; TwoDShape.prototype.name = '2D shape'; function Triangle(side, height){ this.side = side; this.height = height; } var F = function(){}; F.prototype = TwoDShape.prototype; Triangle.prototype = new F(); Triangle.prototype.constructor = Triangle; Triangle.prototype.name = 'triangle'; Triangle.prototype.getArea = function(){ return this.side * this.height / 2; } var mu = new Triangle(5, 10); mu.getArea(); // 25 mu.toString(); // "triangle" var s = new Shape(); s.toString(); // "shape" ``` **圍繞原型構建繼承關系!** # uber——子對象訪問父對象的方式 ``` function Shape(){}; Shape.prototype.name = 'shape'; Shape.prototype.toString = function(){ var result = []; // 先檢查是否存在uber屬性 if(this.constructor.uber){ // 調用toString() result[result.length] = this.constructor.uber.toString(); } result[result.length] = this.name; // 放進數組并返回 return result.join(', '); }; function TwoDShape(){}; var F = function(){}; F.prototype = Shape.prototype; TwoDShape.prototype = new F(); TwoDShape.prototype.constructor = TwoDShape; TwoDShape.uber = Shape.prototype; TwoDShape.prototype.name = '2D shape'; function Triangle(side, height){ this.side = side; this.height = height; } var F = function(){}; F.prototype = TwoDShape.prototype; Triangle.prototype = new F(); Triangle.prototype.constructor = Triangle; Triangle.uber = TwoDShape.prototype; // 指向父級原型 Triangle.prototype.name = 'triangle'; Triangle.prototype.getArea = function(){ return this.side * this.height / 2; } var my = new Triangle(5, 10); my.toString(); // "shape, 2D shape, triangle" ``` # 將繼承部分封裝成函數 ``` function extend(Child, Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; } ``` # 屬性拷貝 ``` function extend2(Child, Parent){ var p = Parent.prototype; var c = Child.prototype; for(var i in p){ c[i] = p[i]; } c.uber = p; } extend2()方法的效率要低于extend()方法,主要是前者對部分原型屬性進行了重建。不過,屬性查找操作會更多的停留在對象本身,從而減少了原型鏈上的查找。 ``` # 對象之間的繼承 在對象之間進行直接屬性拷貝 淺copy:拷貝對象在內存中位置的指針 ``` // 直接將現有對象的屬性全部拷貝,淺copy function extendCopy(p){ var c = {}; for(var i in p){ c[i] = p[i]; } c.uber = p; return c; } // 基本對象,模板 var shape = { name: 'shape', toString: function(){ return this.name; } } // 創建新對象 var twoDee = extendCopy(shape); // 擴展 twoDee.name = '2D shape'; twoDee.toString = function(){return this.uber.toString() + ', ' + this.name;}; var triangle = extendCopy(twoDee); triangle.name = 'triangle'; triangle.getArea = function(){ return this.side * this.height /2; } // 用init()函數解決手動設置的繁瑣過程 triangle.side = 5;triangle.height = 10; triangle.getArea(); // 25 triangle.toString(); // "shape, 2D shape, triangle" ``` # 深拷貝 實現方式同淺拷貝,遍歷對象的屬性,在遇到對象引用屬性,再次調用深拷貝函數。 ``` function deepCopy(p, c){ var c = c || {}; for(var i in p){ if(typeof p[i] === 'object'){ c[i] = (p[i].constructor === Array)? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; } var parent = { numbers: [1,2,3], letters: ['a','b','c'], obj: { prop: 1 }, bool: true } var mydeep = deepCopy(parent); mydeep.numbers.push(4,5,6); mydeep.numbers; // [1,2,3,4,5,6] parent.numbers; // [1,2,3] ``` # object() ``` function object(o){ function F(){}; F.prototype = o; return new F(); } function object(o){ var n; function F(){}; F.prototype = o; n = new F(); n.uber = o; return n; } var triangle = object(twoDee); triangle.name = 'triangle'; triangle.getArea = function(){return this.side * this.height / 2;}; ``` 原型繼承:將父對象設置成子對象的原型。 # 原型繼承與屬性拷貝混合應用 繼承,主要目標是將一些現有的功能歸為己有。 * 使用原型繼承的方式克隆現存對象 * 對其他對象使用屬性拷貝的方式 ``` function objectPlus(o, stuff){ var n; function F(){}; F.prototype = o; n = new F(); n.uber = o; for(var i in stuff){ n[i] = stuff[i]; } return n; } ``` 對象o用于繼承,對象stuff用于拷貝方法與屬性。 ``` var shape = { name: 'shape', toString: function(){ return this.name; } } var twoDee = objectPlus(shape, {name: '2D shape', toString: function(){return this.uber.toString() + ', ' + this.name}}); var triangle = objectPlus(twoDee, {name: 'triangle',side: 0, height: 0, getArea: function(){return this.side * this.height / 2; }}); var my = objectPlus(triangle, {side: 4, height: 4}); my.getArea() // 8 my.toString(); // "shape, 2D shape, triangle, triangle" ``` # 多重繼承 ``` // 雙重循環,外層遍歷傳遞的對象,內層復制屬性 function multi(){ var n = {}, stuff, j = 0, len = arguments.length; for(j = 0; j < len; j++){ stuff = arguments[j]; for(var i in stuff){ n[i] = stuff[i]; } } return n; } var shape = { name: 'shape', toString: function(){return this.name} } var twoDee = { name: '2D shape', dimensions: 2 } // 繼承多個對象 var triangle = multi(shape, twoDee, {name: 'triangle',side: 5, height: 10, getArea: function(){return this.side * this.height / 2 }}); triangle.getArea(); // 25 triangle.dimensions; // 2 triangle.toString(); // "triangle" ``` ## 混合插入 mixins 不通過子對象的繼承與擴展來完成繼承 # 寄生式繼承 在創建對象的函數中直接吸收其他對象的功能,然后對其進行擴展并返回。 ``` function object(o){ var n; function F(){}; F.prototype = o; n = new F(); n.uber = o; return n; } var twoD = { name: '2D shape', dimensions: 2 } function triangle(s, h){ var that = object(twoD); that.name = 'triangle'; that.getArea = function(){return this.side * this.height / 2}; that.side = s; that.height = h; return that; } var t = triangle(5, 10); t.dimensions; // 2 var t2 = new triangle(5,5); t2.getArea(); // 12.5 ``` * 將twoD對象克隆進that對象; * 擴展that對象; * 返回that對象; # 構造器借用 子對象構造器通過call()或apply()方法來調用父對象的構造器。 ``` function Shape(id){ this.id = id; } Shape.prototype.name = 'shape'; Shape.prototype.toString = function(){return this.name}; function Triangle(){ Shape.apply(this, arguments); } Triangle.prototype.name = 'triangle'; var t = new Triangle(101); t.name; // "triangle" t.id; // 101 t.toString(); // "[object Object]" ``` ## 借用構造器與原型復制 ``` function extend2(Child, Parent){ var p = Parent.prototype; var c = Child.prototype; for(var i in p){ c[i] = p[i]; } c.uber = p; } function Shape(id){ this.id = id; } Shape.prototype.name = 'shape'; Shape.prototype.toString = function(){return this.name}; function Triangle(){ Shape.apply(this, arguments); } extend2(Triangle, Shape); Triangle.prototype.name = 'triangle'; var t = new Triangle(101); t.toString(); // "Triangle" t.id; // 101 typeof t.__proto__.id; // "undefined" t.uber.name; // "shape" ``` # 小結 實現繼承的方法(模式) * 基于構造器工作的模式; * 基于對象工作的模式; 分類條件: * 是否使用原型; * 是否執行屬性拷貝; * 兩者都有(原型屬性拷貝);
                  <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>

                              哎呀哎呀视频在线观看