OOP

一涂圆、對(duì)象

1.三類JavaScript對(duì)象和兩類屬性的區(qū)分

  • 內(nèi)置對(duì)象:如數(shù)組劫狠、函數(shù)廊驼、日期和正則表達(dá)式。
  • 宿主對(duì)象:由JavaScript解釋器所嵌入的宿主環(huán)境(如web瀏覽器)
    定義钳垮。可以當(dāng)成內(nèi)置對(duì)象把曼。
  • 自定義對(duì)象:由運(yùn)行中的代碼創(chuàng)建的對(duì)象胡岔。
  • 自有屬性:直接在對(duì)象中定義的屬性。
  • 繼承屬性:在對(duì)象的原型對(duì)象中定義的屬性歹袁。

2.創(chuàng)建對(duì)象

//對(duì)象直接量
var book={
  "title": "js";
  "author": "viaphlyn";
}
//new 
//內(nèi)置構(gòu)造函數(shù)
var o=new Object();//創(chuàng)建一個(gè)空對(duì)象坷衍,和{ }一樣
var a=new Array();//創(chuàng)建一個(gè)空數(shù)組,[ ]
//自定義構(gòu)造函數(shù)
var Vehicle = function () {
  this.price = 1000;
};

var v = new Vehicle();
v.price // 1000

二条舔、new

執(zhí)行構(gòu)造函數(shù)(后面的括號(hào)可有可無枫耳。可接受參數(shù))孟抗,返回一個(gè)實(shí)例對(duì)象

1.原理

  • 創(chuàng)建一個(gè)空對(duì)象迁杨,作為將要返回的對(duì)象實(shí)例
  • 將這個(gè)空對(duì)象的原型钻心,指向構(gòu)造函數(shù)的prototype屬性
  • 將這個(gè)空對(duì)象賦值給函數(shù)內(nèi)部的this關(guān)鍵字
  • 開始執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼

2.

  • 不使用new命令,直接調(diào)用構(gòu)造函數(shù)會(huì)使構(gòu)造函數(shù)就變成了普通函數(shù)铅协,并不會(huì)生成實(shí)例對(duì)象捷沸。this這時(shí)代表全局對(duì)象。
    (可使用嚴(yán)格模式狐史,即第一行加上use strict避免)
  • 函數(shù)內(nèi)部可以使用new.target屬性痒给。如果當(dāng)前函數(shù)是new命令調(diào)用,new.target指向當(dāng)前函數(shù)骏全,否則為undefined

三苍柏、object對(duì)象和繼承

  • Object.getOwnPropertyNames
    返回一個(gè)數(shù)組,成員是對(duì)象本身的所有屬性的鍵名姜贡,不包含繼承的屬性鍵名序仙。
Object.getOwnPropertyNames(Date)
//Array [ "UTC", "parse", "now", "prototype", "length", "name" ]
  • Object.keys
    只獲取那些可以枚舉的屬性
  • Object.prototype.hasOwnProperty()
    返回一個(gè)布爾值,判斷某個(gè)屬性定義在對(duì)象自身鲁豪,還是定義在原型鏈上潘悼。
    唯一一個(gè)處理對(duì)象屬性時(shí),不會(huì)遍歷原型鏈的方法爬橡。
  • in運(yùn)算符
    返回一個(gè)布爾值治唤,表示一個(gè)對(duì)象是否具有某個(gè)屬性。不區(qū)分該屬性是對(duì)象自身的屬性糙申,還是繼承的屬性宾添。
  • for...in循環(huán)
    獲得對(duì)象的所有可枚舉屬性(不管是自身的還是繼承的)

四、Javascript面向?qū)ο箢惡皖惖睦^承怎么實(shí)現(xiàn)

每個(gè)函數(shù)(function)本身就是一個(gè)構(gòu)造函數(shù)(constructor)柜裸,就是一個(gè)類缕陕。
同一個(gè)構(gòu)造函數(shù)的多個(gè)實(shí)例之間,無法共享屬性疙挺,從而造成對(duì)系統(tǒng)資源的浪費(fèi)扛邑。

// 構(gòu)造函數(shù)模式
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sayHi = function() {
        alert("Hi, I'm " + this.name);
    };
}
var zhangsan = new Person("張三", 20);
var lisi = new Person("李四", 21);
//alert(zhangsan.sayHi === lisi.sayHi); // false,問題所在
// 構(gòu)造函數(shù)+原型組合模式
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayHi = function() {
    alert("Hi, I'm " + this.name);
};

var zhangsan = new Person("張三", 20);
var lisi = new Person("李四", 21);
alert(zhangsan.sayHi === lisi.sayHi); // true

2.最簡(jiǎn)單直接的方式: 屬性拷貝;雖然實(shí)現(xiàn)了原型屬性的繼承铐然,但有一個(gè)非常明顯的缺陷:子類實(shí)例無法通過父類的 instanceof 驗(yàn)證蔬崩,即子類的實(shí)例不是父類的實(shí)例。

// 拷貝繼承
function extend(destination, source) {
    for (var property in source) {
        destination[property] = source[property];
    }
}
extend(SubClass.prototype, SuperClass.prototype);

3.通過原型鏈來實(shí)現(xiàn)繼承:

// 原型鏈繼承
function User(name, age, password) {
    // 繼承特權(quán)成員
    Person.call(this, name, age);
    this.password = password;
}
// 繼承原型
User.prototype = new Person();
// 修改了原型指針搀暑,需重新設(shè)置 constructor 屬性
User.prototype.constructor = User;
var zhangsan = new User("張三", 20, "123456");
zhangsan.sayHi(); // Hi, I'm 張三

五沥阳、 prototype對(duì)象

  • 所有對(duì)象=>......=>Object.prototype=>null
  • 讀取對(duì)象的某個(gè)屬性時(shí)。沿著“原型鏈”去找自点,如果直到最頂層的Object.prototype還是找不到桐罕,則返回undefined。
  • prototype對(duì)象有一個(gè)constructor屬性,默認(rèn)指向prototype對(duì)象所在的構(gòu)造函數(shù)功炮〗η保可以被所有實(shí)例對(duì)象繼承。
    可用來分辨原型對(duì)象到底屬于哪個(gè)構(gòu)造函數(shù)
function F() {};
var f = new F();

f.constructor === F // true
f.constructor === RegExp // false

可以從實(shí)例新建另一個(gè)實(shí)例死宣。

function Constr() {}
var x = new Constr();

var y = new x.constructor();
y instanceof Constr // true

constructor屬性表示原型對(duì)象與構(gòu)造函數(shù)之間的關(guān)聯(lián)關(guān)系,如果修改了原型對(duì)象碴开,一般會(huì)同時(shí)修改constructor屬性毅该,防止引用的時(shí)候出錯(cuò)。

  • instanceof運(yùn)算符
    返回一個(gè)布爾值潦牛,表示某個(gè)對(duì)象是否為指定的構(gòu)造函數(shù)的實(shí)例眶掌。
v instanceof Vehicle
// 等同于
Vehicle.prototype.isPrototypeOf(v)

可以巧妙地解決,調(diào)用構(gòu)造函數(shù)時(shí)巴碗,忘了加new命令的問題朴爬。

function Fubar (foo, bar) {
  if (this instanceof Fubar) {
    this._foo = foo;
    this._bar = bar;
  }
  else {
    return new Fubar(foo, bar);
  }
}
  • Object.getPrototypeOf
    返回一個(gè)對(duì)象的原型。這是獲取原型對(duì)象的標(biāo)準(zhǔn)方法橡淆。

  • Object.setPrototypeOf
    為現(xiàn)有對(duì)象設(shè)置原型召噩,返回一個(gè)新對(duì)象。
    接受兩個(gè)參數(shù)逸爵,第一個(gè)是現(xiàn)有對(duì)象具滴,第二個(gè)是原型對(duì)象。

  • Object.prototype.isPrototypeOf()
    判斷一個(gè)對(duì)象是否是另一個(gè)對(duì)象的原型

  • Object.prototype.__ proto__
    指向當(dāng)前對(duì)象的原型對(duì)象师倔,即構(gòu)造函數(shù)的prototype屬性构韵。可以改寫某個(gè)對(duì)象的原型對(duì)象
    __ proto__屬性只有瀏覽器才需要部署趋艘,其他環(huán)境可以沒有這個(gè)屬性疲恢,而且前后的兩根下劃線,表示它本質(zhì)是一個(gè)內(nèi)部屬性瓷胧,不應(yīng)該對(duì)使用者暴露显拳。因此,應(yīng)該盡量少用這個(gè)屬性搓萧,而是用Object.getPrototypeof()(讀任堋)和Object.setPrototypeOf()(設(shè)置),進(jìn)行原型對(duì)象的讀寫操作矛绘。
    原型鏈可以用__ proto__很直觀地表示耍休。

  • 獲取實(shí)例對(duì)象obj的原型對(duì)象,有三種方法货矮。

    • obj.__ proto__
    • obj.constructor.prototype//在手動(dòng)改變?cè)蛯?duì)象時(shí)羊精,可能會(huì)失效。
    • Object.getPrototypeOf(obj)//推薦
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市喧锦,隨后出現(xiàn)的幾起案子读规,更是在濱河造成了極大的恐慌,老刑警劉巖燃少,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件束亏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡阵具,警方通過查閱死者的電腦和手機(jī)碍遍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阳液,“玉大人怕敬,你說我怎么就攤上這事×泵螅” “怎么了东跪?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鹰溜。 經(jīng)常有香客問我虽填,道長,這世上最難降的妖魔是什么曹动? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任卤唉,我火速辦了婚禮,結(jié)果婚禮上仁期,老公的妹妹穿的比我還像新娘桑驱。我一直安慰自己,他們只是感情好跛蛋,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布熬的。 她就那樣靜靜地躺著,像睡著了一般赊级。 火紅的嫁衣襯著肌膚如雪押框。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天理逊,我揣著相機(jī)與錄音橡伞,去河邊找鬼。 笑死晋被,一個(gè)胖子當(dāng)著我的面吹牛兑徘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播羡洛,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼挂脑,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起崭闲,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤肋联,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后刁俭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體橄仍,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年牍戚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侮繁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翘魄,死狀恐怖鼎天,靈堂內(nèi)的尸體忽然破棺而出舀奶,到底是詐尸還是另有隱情暑竟,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布育勺,位于F島的核電站但荤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏涧至。R本人自食惡果不足惜腹躁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望南蓬。 院中可真熱鬧纺非,春花似錦、人聲如沸赘方。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窄陡。三九已至炕淮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跳夭,已是汗流浹背涂圆。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留币叹,地道東北人润歉。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像颈抚,于是被迫代替她去往敵國和親卡辰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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