总结 构造函数与非构造函数 原型继承的一个方法
這兩天真的一直在看原型以及繼承之間的千絲萬縷,哇,收獲頗多,不過所謂溫故知新,還是要多復(fù)習(xí)復(fù)習(xí)知識點(diǎn),才能察覺那些之前不易發(fā)現(xiàn)的小小sparkle
真心推薦MDN文檔——對象原型,JavaScript 中的繼承,文檔指出了很多原理性的東西,所謂飲水思源,大家千萬不要輕易就相信別人說什么好哇就像挖到寶藏一樣,要多實(shí)踐,多探索原理性的東西你才能真正把它掌握,它才真的是你的東西。
期間我還參考了阮一峰老師的Javascript 面向?qū)ο缶幊?#xff08;一):封裝,Javascript面向?qū)ο缶幊?#xff08;二):構(gòu)造函數(shù)的繼承
Javascript面向?qū)ο缶幊?#xff08;三):非構(gòu)造函數(shù)的繼承
廖雪峰老師的原型繼承
在MDN文檔以及廖雪峰老師那里都提到了構(gòu)造函數(shù)繼承的一種方法:(這里主要說明繼承的一個(gè)辦法,原理性的說明請看以上推薦鏈接)
function Person(first, last, age, gender, interests) {this.name = {first,last};this.age = age;this.gender = gender;this.interests = interests; };Person.prototype.greeting = function() {alert('Hi! I\'m ' + this.name.first + '.'); };這里先說明一下,在構(gòu)造函數(shù)中,屬性最好都寫在構(gòu)造函數(shù)里,而方法最后都寫在prototype(原型對象)里,這樣層次比較分明,但是如果是常屬性(值不變),那么他可以寫進(jìn)prototype里,這樣可以減少內(nèi)存的占據(jù)
我們現(xiàn)在要?jiǎng)?chuàng)建一個(gè)Teacher類,需要繼承Person的所有屬性和方法,
同時(shí)也包括:
一個(gè)新的屬性subject——這個(gè)屬性包含了教師教授的學(xué)科。
一個(gè)被更新的greeting()方法,這個(gè)方法打招呼聽起來比一般的greeting()方法更正式一點(diǎn)——對于一個(gè)教授一些學(xué)生的老師來說。
MDN文檔的做法是:
function Teacher(first, last, age, gender, interests, subject) {// 調(diào)用person構(gòu)造函數(shù),綁定this變量:Person.call(this, first, last, age, gender, interests); this.subject = subject; }Teacher.prototype = Object.create(Person.prototype); Teacher.prototype.constructor = Teacher;?而這里廖雪峰老師的做法的第一步也是(與廖老師文章里例子不同但原理相似)
Person.call(this, first, last, age, gender, interests); this.subject = subject;之后他指出,調(diào)用了Person構(gòu)造函數(shù)不等于繼承了Person,Teacher創(chuàng)建的對象的原型是:
new Teacher() ----> Teacher.prototype ----> Object.prototype ----> null必須想辦法把原型鏈修改為:
new Teacher() ----> Teacher.prototype ----> Person.prototype ----> Object.prototype ----> null我們必須借助一個(gè)中間對象來實(shí)現(xiàn)正確的原型鏈,這個(gè)中間對象的原型要指向Person.prototype。為了實(shí)現(xiàn)這一點(diǎn),參考道爺(就是發(fā)明JSON的那個(gè)道格拉斯)的代碼,中間對象可以用一個(gè)空函數(shù)F來實(shí)現(xiàn):?
// 空函數(shù)F: function F() { }// 把F的原型指向Student.prototype: F.prototype = Person.prototype;// 把Teacher的原型指向一個(gè)新的F對象,F對象的原型正好指向Person.prototype: Teacher.prototype = new F();// 把PrimaryStudent原型的構(gòu)造函數(shù)修復(fù)為Teacher: Teacher.prototype.constructor = Teacher;?
重寫Teacher的greeting函數(shù):?
Teacher.prototype.greeting = function() {var prefix;if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {prefix = 'Mr.';} else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {prefix = 'Mrs.';} else {prefix = 'Mx.';}alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); };驗(yàn)證:?
var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');teacher1.name.first; teacher1.interests[0]; teacher1.bio(); teacher1.subject; teacher1.greeting();?廖老師用空函數(shù)的方法實(shí)現(xiàn)了間接繼承又不占用多少空間,Teacher.prototype的改寫也不會影響上一級的prototype,妙也!
但是為什么MDN文檔用
Teacher.prototype = Object.create(Person.prototype);就基本全搞定繼承了呢?
帶著好奇我查了這個(gè)函數(shù)的原理
Object.create = function (o) {var F = function () {};F.prototype = o;return new F();};哈哈哈哈,這不是跟廖老師的方法一樣嘛,也是造一個(gè)空函數(shù),然后間接實(shí)現(xiàn)函數(shù)的繼承!
?
而非構(gòu)造函數(shù)中,阮老師總結(jié)的第一個(gè)方法 object()方法,其原理類似于Object.create()
function object(o) {function F() {}F.prototype = o;return new F();}?
var Chinese = {nation:'China',greeting:function (name) {alert('Hi! I\'m ' + name+' from '+this.nation+ '.');}};var Doctor =Object.create(Chinese);Doctor.career='doctor';Doctor.greeting=function(name){alert('Hi! I\'m a ' + this.career+' from '+this.nation+ ',my name is '+name+ ' .');};alert(Doctor.nation);//ChinaDoctor.greeting('Emma');//Hi! I'm a doctor from China,my name is Emma .大家可以試試看。?
好的,總結(jié)到此啦,阮一峰老師提到了很多構(gòu)造函數(shù)的繼承方法,但是各有利弊吧,原型以及繼承這塊‘深海‘’還是需要我們多去翻滾才行,這里順便拋一個(gè)new方法原理,自己好好瞎捉摸吧哈哈哈哈
總結(jié)
以上是生活随笔為你收集整理的总结 构造函数与非构造函数 原型继承的一个方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高仿人人android梦想版终极源码发送
- 下一篇: 微信小程序教程、微信小程序开发资源下载汇