繼承

繼承是什么?

在面向?qū)ο蟮乃枷胫懈蚯瑥V義的繼承是子對(duì)象擁有父對(duì)象的一切方法與屬性辞友。而JavaScript有著更特殊的原型繼承。
上次我們已經(jīng)介紹了JavaScript中獨(dú)有的原型及其原型鏈這一概念震肮,JS的原型繼承正式基于這兩者而實(shí)現(xiàn)的称龙。那么什么是原型繼承呢?子對(duì)象能夠使用父原型對(duì)象中的一切方法屬性卻不占用自己的內(nèi)存空間戳晌。一句話解釋:我是公共資源鲫尊,能用卻不被擁有。

例如:學(xué)校需要錄入學(xué)校一年級(jí)男生的信息沦偎,樣本個(gè)例的差異僅僅是姓名疫向,所以僅需為每個(gè)新對(duì)象添加一個(gè)姓名的屬性即可。但此時(shí)豪嚎,粗心的管理員把這份信息表和女生的弄混了搔驼,然而每個(gè)對(duì)象并沒有性別這個(gè)屬性,如何做到呢侈询?

function Person(name){
  this.name = name;
}
Person.prototype.gender = "male";
Person.prototype.selfSay = function(){console.log("my name is " + this.name;)}
var p1 = new Person("xiaoming");
var p2 = new Person("xiaohua");
原型圖

我們創(chuàng)建了構(gòu)造函數(shù)Person舌涨,只有一個(gè)屬性name。顯然妄荔,通過(guò)Person new出來(lái)的對(duì)象p1,p2都會(huì)擁有name屬性泼菌。我們額外的為Person.prototype這個(gè)原型對(duì)象,設(shè)置了gender:male,以及方法selfSay啦租。p1,p2本身并不具備gender屬性和selfSay方法哗伯,卻能調(diào)用它:

p1.gender;   //male
p2.selfSay(); // my name is xiaohua

這種繼承方式最大的好處就是,設(shè)置公共資源篷角,減少內(nèi)存空間的占用焊刹。

有幾種常見創(chuàng)建對(duì)象的方式? 舉例說(shuō)明?

  • 直接創(chuàng)建
var xiaoming = {
     name:"xiaoming", 
     age:18,
     gender:"male"
};
var xiaomei = {
     name:"xiaomei",
     age:18,
     gender:"female"
} 
  • 構(gòu)造函數(shù)
function Person(name,age,gender){
     this.name=name;
     this.age=age;
     this.gender = gender;
}
var xiaoming = new Person("xiaoming",18,"male");
var xiaomei = new Person("xiaomei",18,"female");
  • 工廠模式
function factory(name,age,gender){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.gender=gender;
    return obj;
}
var xiaoming = factory("xiaoming",18,male);
var xiaomei = factory("xiaomei",18,female);
  • 原型
function Person(name,gender){
    this.name = name;
    this.gender = gender;
}
Person.prototype.age = 18;
var xiaoming = new Person("xiaoming","male");
var xiaomei = new Person("xiaomei","female");

下面兩種寫法有什么區(qū)別?

//方法1
function People(name, sex){
    this.name = name;
    this.sex = sex;
    this.printName = function(){
        console.log(this.name);
    }
}
var p1 = new People('饑人谷', 2)

//方法2
function Person(name, sex){
    this.name = name;
    this.sex = sex;
}

Person.prototype.printName = function(){
    console.log(this.name);
}
var p1 = new Person('若愚', 27);

兩種方法的p1對(duì)象均能使用,區(qū)別在于PrintName這個(gè)方法存放在哪。方法一中虐块,每個(gè)新創(chuàng)建的子對(duì)象都擁有方法PrintName俩滥,而方法法二中子對(duì)象是不存儲(chǔ)PrintName方法的,而是通過(guò)原型鏈調(diào)用該方法贺奠。

Object.create有什么作用霜旧?兼容性如何?如何使用儡率?

Object.create(proto [, propertiesObject ])方法創(chuàng)建一個(gè)擁有指定原型和若干個(gè)指定屬性的對(duì)象挂据。它是ES5的新方法(IE9以上支持)。

  • 第一個(gè)參數(shù)為必選項(xiàng)儿普,作為被拷貝的對(duì)象原型崎逃。
  • 第二個(gè)參數(shù)為可選項(xiàng),是新對(duì)象的屬性描述符眉孩,格式如下:
    數(shù)據(jù)屬性
    writable:是否可任意寫
    configurable:是否能夠刪除个绍,是否能夠被修改
    enumerable:是否能用 for in 枚舉
    value:值
    訪問(wèn)屬性:
    get(): 訪問(wèn)
    set(): 設(shè)置

例:

var obj = {
    a:function(){
        console.log("I am a.")
    },
    b:function(){
        console.log("I am b.")
    }
}
var newObj = Object.create(obj,{
    c:{ 
        value:"CCCC",
        writable:true
    },
    d:{
        configurable: false,
        get: function() { return d; },
        set: function(value) { d=value }
    }
});

console.log(newObj.a());   //I am a.
console.log(newObj.c);     // CCCC
newObj.c = "DDDDD"         
console.log(newObj.c);     //DDDDD
newObj.d = 100;
console.log(newObj.d);     //100

hasOwnProperty有什么作用? 如何使用浪汪?

判斷一個(gè)屬性是否為該對(duì)象的自身屬性巴柿,如:

function People(name){
    this.name = name;
}
var xiaoming = new People("xiaoming");
xiaoming.age = 18;
xiaoming.hasOwnProperty("name");  //false
xiaoming.hasOwnProperty("age")    //true

實(shí)現(xiàn)Object.create的 polyfill(基于hasOwnProperty)

直接貼的MDN文檔,我按自己的意思來(lái)理解一下:

//當(dāng)沒有這種方法時(shí)吟宦,創(chuàng)建該方法篮洁。
if(!Object.create){                                
    Object.create = (function(){
//準(zhǔn)備工作:1.建立一個(gè)臨時(shí)的空對(duì)象 ;2.提取hasOwnProperty方法 
        function Temp(){};                               
        var hasOwn = Object.prototype.hasOwnProperty;   
        return function(o){
//先判斷傳進(jìn)來(lái)的參數(shù)是否是一個(gè)單純的對(duì)象殃姓,例如函數(shù)就不是袁波,所以函數(shù)應(yīng)當(dāng)傳遞Function.prototype;
            if(typeof o != "object"){
                throw TypeError("Object prototype may only be an Object or null");
            }
//讓臨時(shí)對(duì)象的prototype指向傳入?yún)?shù)o這個(gè)原型對(duì)象,用Temp構(gòu)造出對(duì)象obj蜗侈,顯然obj此時(shí)沒有自有屬性篷牌。
            Temp.prototype = o;
            var obj = new Temp();
            Temp.prototype = null;
//我們知道Object.create()是可以傳入兩個(gè)參數(shù)的,這里這種寫法不禁止你傳入多個(gè)參數(shù)踏幻,但是至多只有
//兩個(gè)有效參數(shù)枷颊,當(dāng)傳入兩個(gè)或兩個(gè)以上參數(shù)時(shí),只取第二個(gè)參數(shù)该面。按照Object.create()原格式夭苗,第二個(gè)
//參數(shù)應(yīng)該是一個(gè)對(duì)象,對(duì)象里有各種屬性隔缀,所以在此遍歷所有屬性题造,并將其賦予obj;至此猾瘸,obj已經(jīng)完全
//復(fù)制了o對(duì)象界赔,return即可丢习;
            if(arguments.length > 1){
                var Properties = Object(arguments[1]);
                for (var prop in Properties){
                    if(hasOwn.call(Properties,prop)){
                        obj[prop] = Properties[prop];
                    }
                }
            }
            return obj;
        }
    })();
}

如下代碼中call的作用是什么?

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    Person.call(this, name, sex);    //調(diào)用Person函數(shù),同時(shí)將作用域由window變?yōu)閠his(調(diào)用Male函數(shù)的對(duì)象)
    this.age = age;
}

補(bǔ)全代碼淮悼,實(shí)現(xiàn)繼承

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}

Person.prototype.getName = function(){
    console.log(this.name);
};    

function Male(name, sex, age){
    Person.call(this,name,sex)
    this.age = age;
}
var obj = Object.create(Person.prototype);
Male.prototype = obj;
obj.constructor = Male;  
Male.prototype.getAge = function(){
    console.log(this.age);
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咐低,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子袜腥,更是在濱河造成了極大的恐慌见擦,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羹令,死亡現(xiàn)場(chǎng)離奇詭異锡宋,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)特恬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)徐钠,“玉大人癌刽,你說(shuō)我怎么就攤上這事〕⒇ぃ” “怎么了显拜?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)爹袁。 經(jīng)常有香客問(wèn)我远荠,道長(zhǎng),這世上最難降的妖魔是什么失息? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任譬淳,我火速辦了婚禮,結(jié)果婚禮上盹兢,老公的妹妹穿的比我還像新娘邻梆。我一直安慰自己,他們只是感情好绎秒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布浦妄。 她就那樣靜靜地躺著,像睡著了一般见芹。 火紅的嫁衣襯著肌膚如雪剂娄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天玄呛,我揣著相機(jī)與錄音阅懦,去河邊找鬼。 笑死把鉴,一個(gè)胖子當(dāng)著我的面吹牛故黑,可吹牛的內(nèi)容都是我干的儿咱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼场晶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼混埠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诗轻,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钳宪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后扳炬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吏颖,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年恨樟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了半醉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡劝术,死狀恐怖缩多,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情养晋,我是刑警寧澤衬吆,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站绳泉,受9級(jí)特大地震影響逊抡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜零酪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一冒嫡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧四苇,春花似錦灯谣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至罗售,卻和暖如春辜窑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寨躁。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工穆碎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人职恳。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓所禀,卻偏偏與公主長(zhǎng)得像方面,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子色徘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 繼承有什么作用? (難度:3*) 繼承可以使一個(gè)對(duì)象直接使用另一個(gè)對(duì)象的屬性和方法恭金。 有幾種常見創(chuàng)建對(duì)象的方式? ...
    coolheadedY閱讀 524評(píng)論 0 0
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,421評(píng)論 3 12
  • 1、構(gòu)造函數(shù)模式 [url=]file:///C:/Users/i037145/AppData/Local/Tem...
    橫沖直撞666閱讀 849評(píng)論 0 0
  • 創(chuàng)建對(duì)象 工廠模式 => 構(gòu)造函數(shù)模式 => 原型對(duì)象模式 => 構(gòu)造函數(shù)模式+原型對(duì)象模式 工廠模式 構(gòu)造函數(shù)模...
    老虎愛吃母雞閱讀 253評(píng)論 0 0
  • 問(wèn)答 1.繼承有什么作用褂策? 繼承是指一個(gè)對(duì)象可以使用另一個(gè)對(duì)象的屬性和方法横腿。JavaScript中由于沒有類(ES...
    饑人谷_任磊閱讀 321評(píng)論 0 0