- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- JavaScript面向對象的示例分析
這篇文章主要介紹JavaScript面向對象的示例分析,文中介紹的非常詳細,具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
每一個(gè)對象都有原型,指向另一個(gè)對象,另一個(gè)對象也有自己的原型,就這樣由原型的原型構成的鏈條就叫原型鏈。
原型鏈的盡頭
如果一個(gè)原型鏈是,沒(méi)用盡頭的,那么在查找一原型鏈上不存在的屬性時(shí),就會(huì )一直查找下去,存在死循環(huán)了。顯然不是這樣的,那么原型鏈的盡頭是什么?
看代碼~
// obj字面量創(chuàng )建方法類(lèi)似于 new Object() // 那么 obj對象就是Object的一個(gè)實(shí)例,也就是說(shuō)obj.__proto__ === Object.prototype var obj = { name: "fzb", }; // 那么obj.__proto__ 或者 Oject.prototype 的__proto__ 是什么? 答案是: null console.log(obj.__proto__); // [Object: null prototype] {} console.log(obj.__proto__.__proto__); // null
[Object: null prototype] {}
的特殊之處:
1、該對象存在原型屬性,只是原型指向了null
,就是已經(jīng)是頂層原型了。
2、該對象上還存在許多其他的方法,只是不可枚舉,看不到。
上方例子的內存圖
原型鏈最頂層的原型對象就是Object的原型對象
例子:
function Student(sno, name) { this.sno = sno; this.name = name; } const stu = new Student(201801, "fzb"); console.log(stu); // Student { sno: 201801, name: 'fzb' } console.log(stu.__proto__); // {} console.log(stu.__proto__.__proto__); // [Object: null prototype] {} console.log(Student.__proto__); // {} /* ***************后面將具體講解注釋內容*************** * 為什么不是 Student.__proto__ = [Object: null prototype] {} * 是因為 Student.__proto__ = Function.prototype * Function.prototype.__proto__ = Object.prototype = [Object: null prototype] {} * ***************后面將具體講解注釋內容*************** */ console.log(Student.__proto__.__proto__); // [Object: null prototype] {}
內存圖:
繼承可以重復利用代碼,子類(lèi)可以使用
例子:
function Person() { this.name = "fzb"; } Person.prototype.running = function () { console.log(this.name + "正在跑步~"); }; function Student(sno) { this.sno = sno; } Student.prototype = new Person(); // 重寫(xiě)整個(gè)原型對象之后,要重新配置 constructor Object.defineProperty(Student.prototype, "constructor", { configurable: true, enumerable: false, writable: true, value: Student, }); Student.prototype.studying = function () { console.log(this.name + "正在學(xué)習"); }; const stu = new Student(201801); stu.running(); // fzb正在跑步~ stu.studying(); // fzb正在學(xué)習
內存圖:
缺陷
1> 在打印子類(lèi)對象時(shí),有些屬性本應該打印出來(lái)的,但是因為在父類(lèi)上,無(wú)法打印出來(lái)。
2> 多個(gè)子類(lèi)對象在進(jìn)行某些操作時(shí),會(huì )出現相互影響。
// 在上方例子上,加一點(diǎn)點(diǎn)代碼, function Person() { this.name = "fzb"; this.friends = []; // 增加一個(gè)屬性 } const stu1 = new Student(201801); stu1.friends.push("zzw"); const stu2 = new Student(201801); console.log(stu2.friends); // [ 'zzw' ] // stu2上取到了stu1的friends屬性,這是不可以的
3> 無(wú)法傳遞參數,有些屬性存在父類(lèi)構造函數內,子類(lèi)實(shí)例化時(shí),初始化參數無(wú)法傳入到父類(lèi)。
在子類(lèi)構造函數內,調用構造函數。使改變父類(lèi)構造函數內的this指向,然后父類(lèi)在this上添加的屬性就會(huì )在子類(lèi)實(shí)例化的對象上。
function Person(name) { this.name = name; this.friends = []; } Person.prototype.running = function () { console.log(this.name + "正在跑步~"); }; function Student(sno, name) { Person.call(this, name); // 添加代碼 this.sno = sno; } Student.prototype = new Person(); // 重寫(xiě)整個(gè)原型對象之后,要重新配置 constructor Object.defineProperty(Student.prototype, "constructor", { configurable: true, enumerable: false, writable: true, value: Student, }); Student.prototype.studying = function () { console.log(this.name + "正在學(xué)習"); }; const stu1 = new Student(201801,"stu1"); stu1.friends.push("zzw"); const stu2 = new Student(201802,"stu2"); console.log(stu2.friends); // []
這時(shí)原型鏈實(shí)現繼承的三個(gè)弊端,就解決的。但是又出現了新的缺陷。
缺陷
1> 父類(lèi)構造函數至少執行了兩次以上
2> 子類(lèi)構造函數的原型對象是父類(lèi)的實(shí)例對象,那么個(gè)對象上的屬性將會(huì )是undefined
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站