JavaScript默認采用原型繼承。雖然沒有類(class)的概念,它的函數(function)可以充當構造器(constructor)。構造器結合this,new可以構建出類似Java的類。因此,JavaScript通過擴展自身能模擬類式(class-based)繼承。
JavaScript和其它面向對象語言一樣,對象類型采用引用方式。持有對象的變量只是一個地址,而基本類型數據是值。當原型上存儲對象時,就可能有一些陷阱。
先看第一個例子
復制代碼 代碼如下:
var create = function() { 
    function Fn() {} 
    return function(parent) { 
        Fn.prototype = parent 
        return new Fn 
    } 
}() 
var parent = { 
    name: 'jack', 
    age: 30, 
    isMarried: false
} 
var child = create(parent) 
console.log(child) 
這時修改child看看會不會影響parent
復制代碼 代碼如下:
child.name = 'lily'
child.age = 20, 
child.isMarried = true
console.log(child) 
console.log(parent) 
結果如下
即修改child不會影響到parent。
再看看另外一個例子
復制代碼 代碼如下:
var create = function() { 
    function Fn() {} 
    return function(parent) { 
        Fn.prototype = parent 
        return new Fn 
    } 
}() 
var parent = { 
    data: { 
        name: 'jack', 
        age: 30, 
        isMarried: false
    }, 
    language: ['Java'] 
} 
var child = create(parent) 
child.data.name = 'lily'
child.data.age = 20 
child.data.isMarried = true
child.language.push('javascript') 
console.dir(child) 
console.dir(parent)
可以看到,此時parent也被修改了,和child的name,age等都一樣了。這是使用原型繼承時需要注意的。
使用繼承時比較好的方式是:
1,數據屬性采用類式繼承(掛在this上),這樣new時也可以通過參數配置
2,方法采用原型繼承,這樣能節省內存,同時子類重寫方法也不會影響父類
下面是一個滿足以上2點的寫類工具函數
復制代碼 代碼如下:
/** 
 * @param {String} className 
 * @param {String/Function} superCls 
 * @param {Function} factory 
 */
function $class(name, superClass, factory) { 
    if (superClass === '') superClass = Object 
    function clazz() { 
        if (typeof this.init === 'function') { 
            this.init.apply(this, arguments) 
        } 
    } 
    var p = clazz.prototype = new superCls 
    clazz.prototype.constructor = clazz 
    clazz.prototype.className = className 
    var supr = superCls.prototype 
    window[className] = clazz 
    factory.call(p, supr) 
}
ES5中加入了一個新API用來實現原型繼承:Object.create。可以用它替代上面自實現的create函數,如下
復制代碼 代碼如下:
var parent = { 
    name: 'jack', 
    age: 30, 
    isMarried: false
} 
var child = Object.create(parent) 
console.log(child) 
新聞熱點
疑難解答
圖片精選