JS類_類的實(shí)例_繼承

類, 類的實(shí)例太示,類的構(gòu)造函數(shù)处坪,類的成員函數(shù)/類原型

1: 類: 具有相同類型的一類實(shí)例的邏輯描述;
2: 類的實(shí)例: 被構(gòu)造函數(shù)出來的具有這個(gè)類的實(shí)例特征的一個(gè)表;
3: 類的成員函數(shù): 完成對(duì)應(yīng)的邏輯凝危,通過this來操作不通的實(shí)例;

//  “function Person”叫做類的構(gòu)造函數(shù)
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// “.get_age”叫做類的方法,又叫做類的成員函數(shù)
// 用 this 操作類的實(shí)例來完成特定的邏輯;
Person.prototype.get_age = function() {
    return this.age;
}

Person.prototype.get_name = function() {
    return this.name;
}
// end

var xiaoming = new Person("xiaoming", 12);

//new 函數(shù)的作用相當(dāng)于手寫了下面這樣的一個(gè)表:
var my_person = {
    //數(shù)據(jù)
        name: "xxxxx",
    age: 12,
        
        //成員函數(shù)
    __proto__: {
        get_name: Person.prototype.get_name,
        get_age: Person.prototype.get_age,
    }
};

//“xiaohong”叫做類的實(shí)例
var xiaohong = new Person("xiaohong", 13);
var xiaotian = new Person("xiaotian", 13);

console.log(xiaotian);
console.log(xiaohong);
console.log(xiaoming);


xiaotian.get_name();
xiaoming.get_name();
xiaotian.get_name();

// xiaotian, xiaoming, xiaohong 者三個(gè)實(shí)例都有相同的結(jié)構(gòu):
// 1:每個(gè)人實(shí)例 都有 name, age,
// 2: 每個(gè)實(shí)例都有一個(gè) (函數(shù))方法get_name, get_age;
// 他們這三個(gè)實(shí)例,屬于同一個(gè)類型;
// 或者說他們?nèi)齻€(gè)實(shí)例潜必,都是Person類
// 把Person看作是一個(gè)類, xiaotian, xiaoming,xiaohong可以看作是類的 3個(gè)實(shí)例;

舉一個(gè)例子:新建一個(gè)Enemy.js文件磺平,寫入

// 類
function Enemy(name, level) {
    this.name = name;
    this.level = level;
}

// “Enemy.prototype”這個(gè)表我們又把他叫做“類原型”;
Enemy.prototype.attack_player = function() {
    console.log("attack_player", this);
}
// 類結(jié)束

module.exports = Enemy;
在 main.js 文件中
var Enemy = require("./Enemy")

var e1 = new Enemy("e1", 1);
e1.attack_player();

var e2 = new Enemy("e2", 2);
e2.attack_player();

繼承

為何要用繼承魂仍?

為了擴(kuò)展“類的原型”拐辽,類的原型不需要構(gòu)造函數(shù)里的實(shí)例

例1:繼承機(jī)制: 貓的代碼---> 波斯貓的代碼(在貓的代碼的基礎(chǔ)上擴(kuò)展波斯貓的代碼
例2:敵人--> 擴(kuò)展成特殊的敵人。在原來敵人的基礎(chǔ)上--> 繼承原來的代碼, --> 再添加;


實(shí)現(xiàn)繼承擦酌,例如:

  1. new 機(jī)制使得 Cat 的空表"__ proto __"被創(chuàng)建俱诸,并攜帶參數(shù) name "Black Cat"
  2. 然后化身為函數(shù) Cat 中的 this
  3. 接著被 .call 顯式傳遞給函數(shù) Animal 中的 this,并攜帶參數(shù)name "Black Cat"
  4. 執(zhí)行函數(shù) Animal赊舶,意味著向 Cat 表中添加和函數(shù) Animal相同地 key 和 value
  5. 打印出 "Black Cat"
function Animal(name){
    this.name = name;
    this.showName = function(){
        console.log(this.name);
    }
}

function Cat(name){
    Animal.call(this, name);
}

var cat = new Cat("Black Cat");
cat.showName();

// step1: 創(chuàng)建一個(gè)BossEnemy的構(gòu)造函數(shù);

function BossEnemy(name, level) {
--------------------------------------------------------------------------------
    // 調(diào)用基類的構(gòu)造函數(shù)
    // 如何繼承“構(gòu)造函數(shù)里的成員”睁搭?
    // new 一個(gè) "BossEnemy",就是在表 BossEnemy 下新建一個(gè)類原型__proto__空表
    // 因?yàn)樵?new 機(jī)制下笼平,函數(shù) BossEnemy 下的 this介袜,就是類原型__proto__空表
    // 接著被 .call 顯式傳遞給構(gòu)造函數(shù) Enemy,構(gòu)造函數(shù) Enemy 下的 this出吹,就被傳遞為表 BossEnemy 下的類原型__proto__空表
    // 執(zhí)行構(gòu)造函數(shù) Enemy遇伞,將構(gòu)造函數(shù) Enemy 下的實(shí)例,添加到表 BossEnemy 下的類原型__proto__空表
    // 又因?yàn)樵?new 機(jī)制捶牢,會(huì)返回表 BossEnemy 下的類原型__proto__表
    // 當(dāng) var boss = new BossEnemy("通天教主", 10) 時(shí)
    // 意思是表 BossEnemy 下的類原型__proto__空表鸠珠,攜帶著由參數(shù)name, level 分別傳過來的 "通天教主", 10
    // 被傳入到構(gòu)造函數(shù) Enemy 中,執(zhí)行的內(nèi)容是向類原型__proto__空表里添加數(shù)據(jù)
    // key = name秋麸,value = 參數(shù)name
    // 所以最終返回的表渐排,就是 attack_player Enemy { name: '通天教主', level: 10, blood: 100 }
    Enemy.call(this, name, level) //這里的this 是 new BossEnemy() 的空表

    // 如何擴(kuò)展自己的成員?
    this.blood = 100;
}

// step2: 把 Enemy 里面所有的原型方法灸蟆,都復(fù)制過來;

// 注意:不能直接這樣寫驯耻。當(dāng)我們修改BossEnemy.prototype原型的時(shí)候,同時(shí)也會(huì)修改到Enemy.prototype炒考。
// 因?yàn)樗麄儍蓚€(gè)變量都指向同一個(gè)“表的實(shí)例”可缚,所以要新建一個(gè)表
// BossEnemy.prototype = Enemy.prototype; 

--------------------------------------------------------------------------------
// 如何繼承“構(gòu)造函數(shù) Enemy 的表 prototype”?
// 寫法1
BossEnemy.prototype = {};
for(var i in Enemy.prototype) {
    BossEnemy.prototype[i] = Enemy.prototype[i];
}

// “規(guī)范的”寫法2
// 通過下面這兩行斋枢,var a 就相當(dāng)于構(gòu)造函數(shù)
// 要繼承基類 Enemy.prototype帘靡,只繼承 prototype。
// 如果直接 new 一個(gè)Enemy瓤帚,除了繼承它的 prototype
// 還會(huì)把函數(shù) Enemy 里的數(shù)據(jù)(this.xxx) 全都拿過來描姚。

var a = function() {}
//a.prototype 指向 Enemy.prototype
a.prototype = Enemy.prototype;
// 用 new 函數(shù)4個(gè)步驟,把類的原型 Enemy.prototype 復(fù)制到表__proto__中戈次。
BossEnemy.prototype = new a(); // {__proto__: Enemy原型}

--------------------------------------------------------------------------------
// 如何擴(kuò)展原型轩勘?
// 獲取到原型以后,就繼承了 Enemy 的原型方法;
BossEnemy.prototype.boss_attack = function() {
    console.log("boss_attack");
}

var boss = new BossEnemy("通天教主", 10);
// 表的訪問
boss.boss_attack();
boss.attack_player();

--------------------------------------------------------------------------------
// 重載
// 根據(jù)優(yōu)先找到表 BossEnemy.prototype.attack_player 的怯邪,會(huì)把Enemy.prototype.attack_player 沖掉
BossEnemy.prototype.attack_player = function() {
    //調(diào)用基類的 prototype
    Enemy.prototype.attack_player.call(this);
// 這里的 this绊寻,還是 new BossEnemy 的表
    console.log("BossEnemy get name");
    return this.name;
}

boss.attack_player();
/*
打印出:
attack_player Enemy { name: '通天教主', level: 10, blood: 100 }
BossEnemy get name
*/

Class函數(shù)

javascript 沒有類,繼承語(yǔ)法的, new, this, 模擬,有些地方些了一個(gè)繼承函數(shù)榛斯。這個(gè)Class函數(shù)观游,能幫我們得到新的類

function Class(class_desic) {
    var new_class = function(name, level) {
        if (class_desic.extend) { // 有基類
            // 調(diào)用基類的構(gòu)造函數(shù)
            class_desic.extend.call(this, name, level);
        }
        // 加一個(gè)初始化的接口 
        if (class_desic.init) {
            class_desic.init.call(this);
        }
    }

    if (class_desic.extend) {
        var a = function() {};
        a.prototype = class_desic.extend.prototype;
        new_class.prototype = new a();  
    }
    else {
        new_class.prototype = {};   
    }

    for(var i in class_desic) {
        if (i == "extend") {
            continue;
        }
        new_class.prototype[i] = class_desic[i];
    }


    return new_class;
}

var BossEnemy2 = Class({
    // 定義寫死的關(guān)鍵字 extend 是繼承自那個(gè)基類
    extend: Enemy, // 對(duì)象的名字

    init: function(){

    },

    boss_attack: function() {

    },

    add_blood: function() {
        console.log("add_blood", this);
/* 
這里的 this 指的也是 b2 的 this
b2 的實(shí)例顯式的綁定過來
這里的 this 也是指后面調(diào)用的實(shí)例
*/
    },
});

var b2 = new BossEnemy2("boss2", 1111);
console.log(b2);
b2.add_blood();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市驮俗,隨后出現(xiàn)的幾起案子懂缕,更是在濱河造成了極大的恐慌,老刑警劉巖王凑,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搪柑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡索烹,警方通過查閱死者的電腦和手機(jī)工碾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來百姓,“玉大人渊额,你說我怎么就攤上這事±萋#” “怎么了旬迹?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)求类。 經(jīng)常有香客問我奔垦,道長(zhǎng),這世上最難降的妖魔是什么尸疆? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任椿猎,我火速辦了婚禮,結(jié)果婚禮上寿弱,老公的妹妹穿的比我還像新娘犯眠。我一直安慰自己,他們只是感情好脖捻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布阔逼。 她就那樣靜靜地躺著,像睡著了一般地沮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上羡亩,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天摩疑,我揣著相機(jī)與錄音,去河邊找鬼畏铆。 笑死雷袋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播楷怒,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛋勺,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了鸠删?” 一聲冷哼從身側(cè)響起抱完,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刃泡,沒想到半個(gè)月后巧娱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烘贴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年禁添,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桨踪。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡老翘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锻离,到底是詐尸還是另有隱情酪捡,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布纳账,位于F島的核電站逛薇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏疏虫。R本人自食惡果不足惜永罚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卧秘。 院中可真熱鬧呢袱,春花似錦、人聲如沸翅敌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蚯涮。三九已至治专,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間遭顶,已是汗流浹背张峰。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棒旗,地道東北人喘批。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親饶深。 傳聞我的和親對(duì)象是個(gè)殘疾皇子餐曹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354