js 對象

特權(quán)方法疏橄、公有方法、靜態(tài)方法


function Animal(name) {  // Animal是一個基于函數(shù)的“類”
  var _name = name;        //私有屬性
    //特權(quán)方法
    this.getName = function() {
        return _name;
    };
    this.setName = function(name) {
        _name = name;
    };
}

Animal.type = function() {
  console.log(this + 'is a private static function')  // Animal的私有靜態(tài)方法
}

Animal.prototype.speak = function() {  // 定義一個原型方法 在js中也叫做公有方法  也是公有靜態(tài)方法略就, 所有的Animal實例共享一份數(shù)據(jù)
  console.log(this.name + ' makes a noise.');
}

var an1 = new Animal()
var an2 = new Animal()

console.log(an1.getName === an2.getName)  // false
console.log(an1.speak === an2.speak) // true
console.log(an1.type) // undefined
console.log(an1.speak) // function() ……

如例子所示:Animal是一個基于函數(shù)的“類”捎迫,an1和an2都是一個Animal的對象實例

  1. 特權(quán)方法:每個對象獨有的方法,每次創(chuàng)建一個實例對象表牢,都會在內(nèi)存中保存一份該特權(quán)方法立砸,特權(quán)方法可以訪問"類"的私有成員
  2. 公有方法:所有實例對象共享的一份屬性和方法,只會在內(nèi)存中保存一份
  3. 靜態(tài)方法:可以定義在原型對象中初茶,也可以定義在類上。定義在類上面的方法是類私有的浊闪,實例對象無法獲取恼布,定義在原型中的方法,實例對象可以獲取
  4. 定義在函數(shù)內(nèi)部的方法和屬性是私有的搁宾,在函數(shù)外部獲取不到折汞,定義在函數(shù)上(如Animal.type)的方法和屬性也是私有,不同之處是可以在外部通過Animal.type獲取到

tips:將實例對象的屬性存儲在實例對象中盖腿,公有的屬性存儲在原型中爽待,可以避免創(chuàng)建許多分公有的數(shù)據(jù)和方法,浪費存儲空間(大部分情況下翩腐,方法都是公有的鸟款,存放在prototype中)

prototype和__proto__

如下所示,定義一個Animal類茂卦,Dog和Cat繼承自Animal


function _inherits(subClass, superClass) {
  subClass.prototype = Object.create(
    superClass && superClass.prototype,
    {
      constructor: { value: subClass, enumerable: false, writable: true, configurable: true
    }
  });
  subClass.__proto__ = superClass
}

function Animal(name) {  // Animal是一個基于函數(shù)的“類”
}


var an1 = new Animal()

var Dog = function (_superClass) {
 _inherits(Dog, _superClass)
  function Dog() {
    return _superClass.apply(this, arguments)
  }
  return Dog
}(Animal)

var Cat = function (_superClass) {
 _inherits(Cat, _superClass)
  function Cat() {
    return _superClass.apply(this, arguments)
  }
  return Cat
}(Animal)


var dog1 = new Dog()
var cat1 = new Cat()

console.log(an1.__proto__ === Animal.prototype)
console.log(Dog.__proto__ === Animal)
console.log(Cat.__proto__ === Animal)
console.log(dog1.__proto__ === Dog.prototype)
console.log(cat1.__proto__ === Cat.prototype)
console.log(Dog.prototype.__proto__ === Animal.prototype)
console.log(Cat.prototype.__proto__ === Animal.prototype)
console.log(an1.constructor === Animal)
console.log(cat1.constructor === Cat)
console.log(dog1.constructor === Dog)

根據(jù)上述的輸出何什,Animal、Dog等龙、Cat之間的關(guān)系处渣,以及他們的原


2 Circles (1).png

型關(guān)系如圖所示:

總結(jié)出:

  1. 每個函數(shù)都有一個屬性prototype伶贰,指向?qū)嵗龑ο蟮脑?/li>
  2. 每個原型對象都有一個constructor,指向構(gòu)造方法
  3. 每個對象都有一個__proto__罐栈,這項該對象的原型對象
    a. 對象可以繼承其原型對象中的方法和屬性
    b. __proto__有些瀏覽器不支持(開發(fā)中最好不要使用 __proto__)黍衙,Object.getPrototypeOf(obj)是es5檢索對象的原型(proto)的標(biāo)準(zhǔn)方法
    c. 每個對象都有一個 __proto__指向它的原型,這就是原型鏈(prototype chain)
    d.instanceof荠诬, object.instanceof(constructor)琅翻,判斷Object的原型鏈中是否存在constructor.prototype,表示一直繼承關(guān)系

繼續(xù)

console.log('\n', Animal.__proto__ === Function.prototype)
console.log(Animal.prototype.__proto__ === Object.prototype)
console.log(Function.__proto__ === Function.prototype)
console.log(Function.prototype.__proto__ === Object.prototype)
console.log(Object.__proto__ === Function.prototype)
console.log(Object.prototype.__proto__ === null)
2 Circles (2).png

繼承

如上栗所示浅妆,Dog類繼承Animal類望迎,根據(jù)圖中繼承的關(guān)系,需要執(zhí)行以下步驟

  1. Dog繼承Animal:Animal.apply(this, arguments)凌外,this指向Dog對象
  2. 設(shè)置Dog.prototype繼承Animal.prototype辩尊,并且設(shè)置Dog.prototype的constructor指向Dog函數(shù):
Dog.prototype = Object.create(
    Animal && Animal.prototype,
    {
      constructor: {
        value: subClass,
        enumerable: false,
        writable: true,
        configurable: true
    }
  });
  1. 設(shè)置Dog.__proto__ = Animal
    上栗babel的extends源碼
  2. \_classCallCheck函數(shù),判斷生成的對象原型鏈上是否存在Constructor.prototype康辑,避免把構(gòu)造函數(shù)當(dāng)做一般函數(shù)使用摄欲,比如把直接調(diào)用Animal()就會報錯'Cannot call a class as a function'
  3. \_inherits函數(shù),設(shè)置subClass. prototype.__proto__ = superClass以及subClass. prototype. constructor = constructor疮薇,設(shè)置subClass.__proto__ = superClass胸墙,.__proto__ 是非標(biāo)準(zhǔn)方法,瀏覽器不支持的時候使用Object.setPrototypeOf(subClass, superClass)
'use strict';

function _possibleConstructorReturn(self, call) {
  if (!self) {
    throw new ReferenceError('this hasn\'t been initialised - super() hasn\'t been called');
  }
  return call && (typeof call === 'object' || typeof call === 'function') ? call : self;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== 'function' && superClass !== null) {
    throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
  }
  subClass.prototype = Object.create(superClass && superClass.prototype,
    { constructor: { value: subClass, enumerable: false, writable: true, configurable: true }
  });
  if (superClass) {
    Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  }
}

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError('Cannot call a class as a function');
  }
}

var Animal = function Animal(name) {
  _classCallCheck(this, Animal);

  this.name = name;
};

var Dog = function (_Animal) {
  _inherits(Dog, _Animal);

  function Dog() {
    _classCallCheck(this, Dog);

    return _possibleConstructorReturn(this, (Dog.__proto__ || Object.getPrototypeOf(Dog)).apply(this, arguments));
  }

  return Dog;
}(Animal);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末按咒,一起剝皮案震驚了整個濱河市迟隅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌励七,老刑警劉巖智袭,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掠抬,居然都是意外死亡吼野,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門两波,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瞳步,“玉大人,你說我怎么就攤上這事腰奋〉テ穑” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵劣坊,是天一觀的道長馏臭。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么括儒? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任绕沈,我火速辦了婚禮,結(jié)果婚禮上帮寻,老公的妹妹穿的比我還像新娘乍狐。我一直安慰自己,他們只是感情好固逗,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布浅蚪。 她就那樣靜靜地躺著,像睡著了一般烫罩。 火紅的嫁衣襯著肌膚如雪惜傲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天贝攒,我揣著相機與錄音盗誊,去河邊找鬼。 笑死隘弊,一個胖子當(dāng)著我的面吹牛哈踱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梨熙,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼开镣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了咽扇?” 一聲冷哼從身側(cè)響起邪财,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎质欲,沒想到半個月后卧蜓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡把敞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了榨惠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奋早。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赠橙,靈堂內(nèi)的尸體忽然破棺而出耽装,到底是詐尸還是另有隱情,我是刑警寧澤期揪,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布掉奄,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏姓建。R本人自食惡果不足惜诞仓,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望速兔。 院中可真熱鬧墅拭,春花似錦、人聲如沸涣狗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镀钓。三九已至穗熬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丁溅,已是汗流浹背唤蔗。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唧瘾,地道東北人措译。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像饰序,于是被迫代替她去往敵國和親领虹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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

  • 內(nèi)容來自《JavaScript高級程序設(shè)計》第三版第6章第3節(jié) 原型鏈 ECMAScript中描述了 原型鏈的概念...
    angelwgh閱讀 235評論 0 0
  • 對象:由多組無序?qū)傩越M成的數(shù)據(jù)結(jié)構(gòu) (鍵值對) 成對出現(xiàn):屬性名 屬性值字面量 簡單對象也存在構(gòu)造函數(shù) (如:...
    月光在心中閱讀 320評論 0 0
  • 對象: 1. 對象中包含一系列的屬性求豫,這些屬性是無序的塌衰。 2. 每個屬性都有一個字符串key和對應(yīng)的value;(...
    一樹青楓閱讀 343評論 0 1
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持蝠嘉,譯者再次奉上一點點福利:阿里云產(chǎn)品券最疆,享受所有官網(wǎng)優(yōu)惠,并抽取幸運大...
    HetfieldJoe閱讀 2,991評論 4 14
  • 人與人之間的差別蚤告,大于人與豬的差別努酸。前者的基因差異是恒定的,可量化的杜恰;后者則完全超出想象获诈,無法預(yù)測。 我們可以學(xué)唱...
    Sunny夕夕閱讀 287評論 0 2