摘要:和我前一篇說過,構造函數模式不流行就是因為他的重用性這種繼承方式的重用性呵呵但是我們也不能否定他的存在,畢竟我以前也用過。
繼承
今天給大家科普一個叫做繼承的大哥。之所以叫做大哥,是因為他確實是所以語言都必須具備的。而且這也是BAT公司前端面試中,必提及的一個知識點。 由于js 是由 大神 在10天之內寫完了,但后來由ECMA262接手優化,最終有了現在豐滿的JS。 但是關于繼承的遺留問題應該算是比較嚴重的。 先說一下基本的js繼承有哪些.
借用構造函數啊~~~ md, 名字怎么這么怪嘞! 這個官方的說法,我們鄉下人管他叫做復制(copy);
來個栗子:
function Father(name){ this.name =name; } function Children(name){ Father.call(this,name); } let jimmy = new Children("jimmy"); console.log(jimmy.name); //jimmy
沒錯,看清楚,其實就是使用了函數對象自帶的方法。call 來創建的。 將父構造函數的屬性給copy到子類上,相當于建立了一個副本。但其實這種方式并沒有什么卵用。 和我前一篇說過,構造函數模式不流行就是因為他的重用性 === 0. 這種繼承方式的重用性(呵呵) <=0. 但是我們也不能否定他的存在,畢竟我以前也用過。
介紹一個當今比較流行的,組合繼承
組合繼承組合就是融合了原型和構造器的一種繼承方法。 這個應該算是一種比較穩妥的繼承方式.
即能排除引用類型造成的問題,又可以實現共享的效果。
function A (){ this.name = "jimmy"; } A.prototype.speak = function(){ console.log(`my name is ${this.name}`); } function B(){ A.call(this); } B.prototype = new A(); B.prototype.constructor = B; var b = new B(); console.log(b.name); //jimmy b.speak(); //my name is jimmy
這種應該算是比較經典了,但這樣會兩次調用到父類型,對內存影響還是比較大的。 所以有人提出中間創建一個寄生組合式繼承. 但這個真的很雞肋。 JS的一個繼承能扯出這么多東西,也是醉了。
但是es6 class 的出現,解決了這一痛點。 雖然這個東西有悖js 的原理(因為在js中是沒有類這個概念的),但是實用性確實相當的好.
所以今天的主角應該是class 這個東西
在es6中新出了一個feature--class. 中文叫做類. 應該算是混合模式的一個總結吧。在使用class的使用,你完全可以不去寫,constructor, prototype之類的東西了.
來個栗子:
//原生的混合模式: function Point(x,y){ this.x = x; this.y = y;} Point.prototype.toString = function () { return "(" + this.x + ", " + this.y + ")"; } var point = new Point(1,2); //使用class的類: class Point { constructor(x, y) { //本質上還是原型鏈上的方法 this.x = x; //這里的this和上面的一樣都代表實例對象 this.y = y; } toString() { return "(" + this.x + ", " + this.y + ")"; } } var point = new Point(1,2);
雖然我打心里是不愿意將類加入js里面(沒準以后就變為標準了),但為了大家的理解,我還是把這個稱為類吧; ):
可以看到類和原型js的寫法的不同吧。我先說一下語法吧。
創建一個類,就和在java里面創建類是一樣的。
初始化使用class + 類名(首字母大寫) + {...}
class Hehe{ ... } var hehe new Hehe();
初始化話,上面也已經說了。在類中需要注意一個叫做constructor的方法,這個就相當于構造函數里面的內容,他會在類初始化時,自動執行. 所以可以在constructor里面傳遞一些參數.
class Jimmy{ constructor(name){ this.name = name; //這里的this和構造函數里面的this的屬性是一致的 } } let jimmy = new Jimmy("jimmy"); console.log(jimmy.name); //jimmy
當然在類中還可以添加方法。具體做法如下:
class Jimmy{ constructor(name){ this.name = name; //這里的this和構造函數里面的this的屬性是一致的 } speak(){ console.log(`my name is ${this.name}`); } } let jimmy = new Jimmy("jimmy"); jimmy.speak(); //my name is jimmy;
需要注意,請不要手賤在每個{} 后面加上 "," 像這樣
class Jimmy{ constructor(name){ this.name = name; }, speak(){ console.log(`my name is ${this.name}`); } }
到時候出個bug, 我看你哭去吧。
而這樣定義的方法其實是存在于Jimmy.prototype 上的。
我們檢驗一下Jimmy的類型;
Jimmy instanceof Function; //true
所以說 其實 類就是js混合模式的一個syntax candy(語法糖).
當然類也可以使用字面量形式書寫(廢話,類本來就是函數類型)
const MyClass = class Me { getClassName() { return Me.name; //這里的Me 就和使用函數是一樣的道理 }}; var MyClass = function Me(){ console.log(Me.name); //Me }
關鍵看你喜歡用哪一種了。
說一說類的繼承吧, 這應該是我最喜歡class的原因了.
在class中是使用extends來實現繼承的效果的. 還有一個特性 super. 這個用來指向父類的實例,如果大家記得應該會了解到上面說的繼承模式吧。 而這里的super算是es6新定義的一個東西。
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y, color) { this.color = color; // 這里會報錯,ignore這句就可以了 super(x, y); //這里相當于初始化父類,然后規定class里面this的指向 this.color = color; // 正確 } show(){ console.log(this.color); console.log(super.x); console.log(this.x); } } var color = new ColorPoint(1,2,"red"); color.show(); //依次得到, red , 1 ,1
我艸,super和this到底應該怎么區分嘞?
很簡單,上面已經說了,super是指向父類的實例,而this是在這里是構造函數上原型的指針。 其實由于繼承,使用this也可以訪問到x; 所以推薦如果你有強迫癥的話,父類上的方法和屬性可以使用super調用,子類自定的屬性和方法使用this調用。 當然我喜歡直接使用this(三包服務)。
還有一點,那我怎么檢測我的父類到底是誰嘞(隔壁王叔叔)?
如果你在瀏覽器的Console 里面,可以直接使用.__proto__來進行檢測的(腳本里不行)。在腳本里,js提供了一個方法getPrototypeOf()來進行檢測
//上述例子 Object.getPrototypeOf(ColorPoint); //Point //相當于瀏覽器里面的 ColorPoint.__proto__; //Point
關于繼承我就扯這么多吧。 雖然說繼承很重要,但我們用的地方不是很多,原因是----因為我們不牛逼。。。 大家如果有空可以去翻一翻jquery或者zepto的源碼,看一看是不是用到了prototype,繼承等相關的技術。而且他們封裝性都是超級好的。沒有一個直接寫在全局里面的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78392.html
摘要:解決的痛點首先我們需要明白和理解和的設計初衷和理念。所有框架要解決的問題應對需求變化,防止大面積重寫。參考文獻漸進式框架理解核心功能原理解析百度網盤視頻學習以及源碼資源提取密碼 vue解決jquery的痛點 首先我們需要明白和理解jquery和vue的設計初衷和理念。 jquery官網給出的開篇介紹是,jquery是一個快,小,功能豐富的js庫,它讓html文檔遍歷和操作,事件處理...
摘要:為什么要面向對象你需要知道的面向對象面向對象并不是針對一種特定的語言,而是一種編程范式。后端傳遞過來顯示工人完成狀態的字段代表未完成,代表已完成。其實這就是如何消除代碼副作用的問題將副作用隔離。 為什么要面向對象? 你需要知道的面向對象 面向對象并不是針對一種特定的語言,而是一種編程范式。但是每種語言在設計之初,都會強烈地支持某種編程范式,比如面向對象的Java,而Javascript...
摘要:之后,在本地目錄生成代碼并且安裝項目依賴的包,最后將本次初始化生成的所有代碼自動提交到遠程倉庫。按照城市評選,分別評選明日之子僅限男性參加和閃亮女神僅限女性參加。 背景: 隨著開發團隊規模不斷發展壯大,在人員增加的同時也帶來了協作成本的增加,業務項目越來越多,類型也各不相同。常見的類型有組件類、活動類、基于React+redux的業務項目、RN項目、Node.js項目等等。如果想要對每...
摘要:示例庫通過記錄來查看定制類名默認的哈希算法是,從前面我們可以發現被編譯成了這樣的字符串。與上面不加等價顯式的局部作用域語法通過示例庫的記錄來查看下的樣式復用對于樣式復用,提供了組合的方式來處理。 showImg(https://segmentfault.com/img/bV9WfX?w=800&h=274);前端發展越來越快,這應該是每個前端開發者的切身感受,但是CSS 是前端領域中進...
閱讀 3052·2021-11-19 11:31
閱讀 3140·2021-09-02 15:15
閱讀 994·2019-08-29 17:22
閱讀 1064·2019-08-29 16:38
閱讀 2469·2019-08-26 13:56
閱讀 840·2019-08-26 12:16
閱讀 1441·2019-08-26 11:29
閱讀 937·2019-08-26 10:12