JavaScript中的Objects, Prototypes和Classes
日常逛街(一個基于kendoUI的文檔在線編輯瀏覽審核發布管理的網站)
看看代碼,看到一段代碼,很懷念的感覺,最近都不怎么見到這么寫的了,可能是用多了npm install了的原因吧...
(類似的這種https://github.com/inolen/quakejs/blob/master/lib/directed-graph.js寫法)
function?CommonClassA(){ this.projectId?=?null; this.aaaLists?=?null; this.aaaObj?=?{}; this.cloneaaaObj?=?{}; this.aaaUrl?=?localStorage.contextPath?+?"/xxx/getAAA.do"; this.aaasUrl?=?localStorage.contextPath?+?"/xxx/getAAALists.do"; } CommonClassA.prototype={ getAAA?:?function(aaa){ var?self?=?this; ????$.ajax({ ???? ????type?:?"post", ???? url??:?...Utils.appendTimeForUrl(self.aaaUrl), ???? data?:?JSON.stringify(aaa), ???? contentType:"application/json", ???? success?:?function(data){ ???? ... ???? }, ???? error?:function(data){ ???? ... ???? }, ???? }); }, getAAALists?:?function(){ ????var?self?=?this; $.ajax({ ????type?:?"post", dataType?:"json", ???? url??:?..., ???? success:function(data){ ???? ... ???? }, ???? error:function(data){ ???? ...; ???? }, }); }, }; var?commonClassA=?new?CommonClassA();
感覺和直接這么寫也沒什么區別:
var?LibraryVM?=?{ $VM__deps:[] SUSPENDED:?0xDEADBEEF, FindLabels:?function?(state)?{} }
于是搜了搜prototype和class相關的對比,感覺下面這篇文章寫得不錯
https://alligator.io/js/objects-prototypes-classes/
摘錄如下:
考慮到javaScript中的幾乎所有內容都是對象這一事實,面向對象的javaScript代碼與其他支持對象的語言完全不同。JS對象系統更多地是基于原型的對象系統。
從C ++背景的,我知道的面向對象的編程范式中,及比類和對象如何非常嚴格的想法應該工作。接觸其他語言(如Java)似乎只會進一步確立這個想法。這些語言在對象和類的工作方式上有其自己的語義;對于新用戶來說,JavaScript是一個很大的啟示。
首先,JavaScript對象的創建方式非常不同。不需要一個類。可以使用new運算符創建對象實例:
let?Reptile?=?new?Object()?{ ?//?... }
或使用函數構造函數
function?Reptile()?{ ?//?... }
其次,JavaScript對象非常靈活。傳統的面向對象語言僅允許屬性修改或屬性槽,而JavaScript則允許對象修改其屬性和方法。即JavaScript對象同時具有屬性和方法槽。
在發現時,我的第一個念頭是“是的,自由!”,但這要付出代價-需要了解JavaScript的原型屬性。對于希望在JavaScript中實現任何面向對象系統的外觀的開發人員來說,原型知識都是必不可少的。
所有JavaScript對象都是從Object構造函數創建的:
Reptile.prototype.doesItDrown?=?function()?{ ??if?(this.canItSwim)?{ ????console.log(`${this.name}?can?swim`); ??}?else?{ ????console.log(`${this.name}?has?drowned`); ??} };
并且prototype允許我們向對象構造函數添加新方法,這意味著以下方法現在存在于的所有實例中Reptile。
Reptile.prototype.doesItDrown?=?function()?{ ??if?(this.canItSwim)?{ ????console.log(`${this.name}?can?swim`); ??}?else?{ ????console.log(`${this.name}?has?drowned`); ??} };
Reptile現在可以創建的對象實例:
croc.__proto__.doesItDrown?=?function()?{ ??console.log(`the?croc?never?drowns`); }; croc.doesItDrown();?//?the?croc?never?drowns alligator.doesItDrown();?//?the?croc?never?drowns
該prototype對的Reptile,現在目標是繼承的基礎上,doesItDrown方法是既可以訪問alligator并croc因為prototype中Reptile有這個方法。該prototype屬性在其所有實例之間共享,并且可以通過__proto__特定實例的屬性進行訪問。
現在,由于存在方法槽,并且prototype在所有實例之間共享一個公共實例屬性,因此可能會出現一些非常巧妙的技巧,這對C ++人士來說很奇怪:
croc.__proto__.doesItDrown?=?function()?{ ??console.log(`the?croc?never?drowns`); }; croc.doesItDrown();?//?the?croc?never?drowns alligator.doesItDrown();?//?the?croc?never?drowns
更改一個實例的prototype屬性或方法,該對象的所有實例都會受到影響。這意味著我們也可以刪除東西。厭倦了溺水的鱷魚可能會這樣做:
delete?croc.__proto__.doesItDrown alligator.doesItDrown(); //TypeError:?alligator.doesItDrown //?is?not?a?function
現在沒有人去游泳。
這只是一個愚蠢的示例,它展示了prototypeJavaScript對對象系統的根本意義,以及它對來自其他面向對象語言的人們的影響如何。
使用ES6語法,已為JavaScript提供了創建類的功能。
但是,真正的類的概念在JavaScript中不存在,但可以通過它進行仿真,prototype并且類語法只是圍繞它的語法糖。因此,了解此行為對于實現ES6類的便利性和局限性很重要。
使用新class語法,Reptile將被定義為:
class?Reptile?{ ??constructor?(name,?canItSwim)?{ ????this.name?=?name; ????this.canItSwim?=?canItSwim; ??} ??doesItDrown?()?{ ???if(this.canItSwim)? ????console.log(`${this.name}?can?swim`); ???else ????console.log(`${this.name}?has?drowned`); ??} } let?alligator?=?new?Reptile("alligator",?true); alligator.doesItDrown();?//alligator?can?swim
這并不意味著它不會為prototype用戶帶來任何新鮮事物,使用ES6類可以避免一些陷阱,例如使new關鍵字對于創建實例是強制性的。
let?croc?=?Reptile("croc",?false); //TypeError:?Class?constructor?Reptile?cannot?be?invoked?without?'new'
這實際上是一件好事,因為它可以防止在使用對象屬性和方法(通常是全局范圍或窗口對象)時訪問錯誤的上下文。
結論
盡管JavaScript現在確實確實缺少真正的私有成員之類的功能。它使通過類語法創建對象成為可能,而不是使原型與來自其他OO語言(如C ++ / Java)的類非常相似。
PS。TC39提出了在JavaScript類中創建真正的私有成員的建議,您可以在此處關注并提出您的意見。如果它要包含在下一個修訂版中,那么我們將有類似以下內容:
class?Foo?{ ??#a;?#b;?//?#?indicates?private?members?here ??#sum?=?function()?{?return?#a?+?#b;?}; } //?personally?this?format?reminds?me?of?$variable?in?PHP. //?I'm?not?sure?if?that's?a?good?thing
其他:
一些關于js原型鏈的討論
https://stackoverflow.com/questions/816071/prototype-based-vs-class-based-inheritance
https://medium.com/%40parsyval/javascript-prototype-vs-class-a7015d5473b
https://juejin.im/post/5db0fec4518825648c3a8770
關于 Kendo UI 開發教程
https://www.w3cschool.cn/kendouidevelopmenttutorial/62s81jv1.html
https://github.com/kendo-labs/bower-kendo-ui
Java JavaScript
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。