麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

淺析JavaScript原型繼承的陷阱

2019-11-20 21:32:02
字體:
供稿:網(wǎng)友

JavaScript默認(rèn)采用原型繼承。雖然沒有類(class)的概念,它的函數(shù)(function)可以充當(dāng)構(gòu)造器(constructor)。構(gòu)造器結(jié)合this,new可以構(gòu)建出類似Java的類。因此,JavaScript通過擴(kuò)展自身能模擬類式(class-based)繼承。

JavaScript和其它面向?qū)ο笳Z言一樣,對象類型采用引用方式。持有對象的變量只是一個(gè)地址,而基本類型數(shù)據(jù)是值。當(dāng)原型上存儲對象時(shí),就可能有一些陷阱。

先看第一個(gè)例子

復(fù)制代碼 代碼如下:

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)

create工具函數(shù)實(shí)現(xiàn)了一個(gè)基本的原型繼承,每次調(diào)用create都會根據(jù)parent對象去復(fù)制一個(gè)新對象,新對象全部的屬性都來自于parent。這里parent有三個(gè)屬性,都是基本數(shù)據(jù)類型:字符串,數(shù)字,布爾。

這時(shí)修改child看看會不會影響parent

復(fù)制代碼 代碼如下:

child.name = 'lily'
child.age = 20,
child.isMarried = true

console.log(child)
console.log(parent)

結(jié)果如下

即修改child不會影響到parent。

再看看另外一個(gè)例子

復(fù)制代碼 代碼如下:

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的兩個(gè)屬性data,language都是引用類型,一個(gè)是對象,一個(gè)是數(shù)組。child仍然繼承與parent,隨后修改了child,結(jié)果如下

可以看到,此時(shí)parent也被修改了,和child的name,age等都一樣了。這是使用原型繼承時(shí)需要注意的。

使用繼承時(shí)比較好的方式是:

1,數(shù)據(jù)屬性采用類式繼承(掛在this上),這樣new時(shí)也可以通過參數(shù)配置

2,方法采用原型繼承,這樣能節(jié)省內(nèi)存,同時(shí)子類重寫方法也不會影響父類

下面是一個(gè)滿足以上2點(diǎn)的寫類工具函數(shù)

復(fù)制代碼 代碼如下:

/**
 * @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)
}

對象類型放在父類原型上時(shí)務(wù)必小心子類修改其,這時(shí)繼承于該父類的所有子類的實(shí)例都將被修改。而這造成的bug很不容易發(fā)現(xiàn)。

ES5中加入了一個(gè)新API用來實(shí)現(xiàn)原型繼承:Object.create??梢杂盟娲厦孀詫?shí)現(xiàn)的create函數(shù),如下

復(fù)制代碼 代碼如下:

var parent = {
    name: 'jack',
    age: 30,
    isMarried: false
}
var child = Object.create(parent)
console.log(child)

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: xxxx69hd一hd | 久久精品中文字幕 | 亚洲小视频在线 | 久久国产综合精品 | 国产九九九九 | 国产91小视频在线观看 | 涩涩操 | 一区二区三区在线视频观看58 | 青青草最新网址 | 欧美一级高清免费 | 精品亚洲夜色av98在线观看 | hdjapanesemassagehd日本 | 精品一区免费 | 人人舔人人舔 | 国产亚洲综合一区二区 | 羞羞的视频 | 人人舔人人舔 | 黄色高清免费网站 | 狠狠干天天 | 伊人av影院 | 手机免费看一级片 | 国产在线1区 | 久久国产一二区 | 久久久久一本一区二区青青蜜月 | 久久精品亚洲精品国产欧美kt∨ | fc2国产成人免费视频 | 久久精品1区2区 | 国产99久久精品 | 国产精品亚洲精品日韩已方 | 羞羞漫画无遮挡观看 | 亚洲极色 | 久久精品79国产精品 | 欧美男女爱爱视频 | 久久久久久久高清 | 福利免费观看 | 九九夜夜| 中文字幕在线资源 | 久久生活片 | 亚州综合图片 | 蜜桃视频在线免费播放 | 久久久久国产成人精品亚洲午夜 |