破解 JS(原型)繼承

來源:互聯網
上載者:User

標籤:href   它的   javascrip   中介   als   isa   edit   inter   call   

總體分為四大類:利用Null 物件作為中介繼承、Object.create 繼承、setPrototypeOf 繼承、拷貝繼承

function Animal(name, age) {  this.name = name;  this.age = age;}Animal.prototype = {  speak: function() {    console.log(‘my name is ‘ + this.name);  }}function Cat() {  Animal.apply(this, arguments);  this.food = ‘mouse‘;}


一、利用Null 物件作為中介繼承

function extend(child, parent) {  var F = function() {};  F.prototype = parent.prototype;  child.prototype = new F();  child.prototype.constructor = child;}

F是Null 物件,所以幾乎不佔記憶體。這其實就是 YUI 實現繼承的方法。

試一試

二、Object.create 繼承

Object.create 會使用指定的原型對象和屬性去建立一個新對象。

function extend(child, parent) {  // 任何一個prototype對象都有一個constructor屬性,指向它的建構函式。  // 使 Cat.prototype 指向 Animal.prototype, 但他有一個副作用:Cat.prototype.constructor指向Animal  child.prototype = Object.create(parent.prototype);  // 修正 constructor  child.prototype.constructor = child;}

試一試

疑問一:為什麼不直接  child.prototype = parent.prototype; ?

  如果這樣的話,child.prototype 會直接引用 parent.prototype 對象,那麼當你對 child.prototype.constructor 進行賦值操作時,就把 parent.prototype.constructor 也給修改了

疑問二:為什麼不用child.prototype = new parent(); ?

   new parent() 確實會建立一個關聯到 child.prototype 的新對象。但如果函數 parent 有一些副作用(比如修改狀態、註冊到其它對象、給 this 添加屬性等等)的話,會影響到 child() 的後代,後果不堪設想!

綜上所訴,Object.create 是最好的選擇,雖然它是建立了一個新對象替換掉了預設的對象。那有沒有直接修改預設對象的方法呢?答案就是 setPrototypeOf

三、setPrototypeOf 繼承

setPrototypeOf 是 ES6新增的輔助函數。下面來做一下對比

// 拋棄預設的 child.prototypechild.prototype = Object.create(parent.prototype);// 直接修改預設的 child.prototypeObject.setPrototypeOf(child.prototype, parent.prototype);

經過對比發現:如果忽略Object.create() 帶來的輕微的損失(拋棄的對象需要進行記憶體回收),它比 ES6 的方法有更好的可讀性。

 四、拷貝繼承

也是 jQuery 實現繼承的方法

// 拷貝繼承function extend() {    var options, src, copy, copyIsArray, clone,        target = arguments[0] || {},        deep = false,        i = 1;        if ( typeof target === ‘boolean‘) {        deep = target;        target = arguments[i] || {};        i++;    }    if ( typeof target !== ‘object‘ && !isFun(target)) {        target = {};    }    // 迴圈一個或多個要拷貝的對象    for( ; i<arguments.length; i++ ) {        if ( (options = arguments[i]) != null ) {            for ( name in options ) {                src = target[name];                copy = options[name];                // 防止死迴圈                if ( target === copy ) {                    continue;                }                copyIsArray = isArray(copy);                if ( deep && copy && ( isPlainObject(copy) || copyIsArray ) ) {                    // 深拷貝                    if ( copyIsArray ) {                        copyIsArray = false;                        clone = src && isArray(src) ? src : [];                    } else {                        clone = src && isPlainObject(src) ? src : {};                    }                    target[name] = extend( deep, clone, copy );                // 防止拷貝 undefined                    } else if ( copy !== undefined ) {                    target[name] = copy;                }            }        }    }    return target;}function isFun(obj) {    return type(obj) === ‘[object Function]‘;}function isPlainObject(obj) {    return type(obj) === ‘[object Object]‘;}function isArray(obj) {    // IE8不支援    if (Array.isArray) {        return Array.isArray(obj);    } else {        return type(obj) === ‘[object Array]‘;    }}function type(obj) {    if ( obj == null ) {        // obj + ‘‘ = ‘null‘/‘undefined‘        return false;    }    return Object.prototype.toString.call(obj);}var object1 = {  apple: 0,  banana: { weight: 52, price: 100 }};var object2 = {  banana: { price: 200 },  cherry: 97};extend(true, object1, object2);

 

 試一試

破解 JS(原型)繼承

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.