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
现在没有人去游泳。
这只是一个愚蠢的示例,它展示了prototype
JavaScript对对象系统的根本意义,以及它对来自其他面向对象语言的人们的影响如何。
使用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
- 点赞
- 收藏
- 关注作者
评论(0)