JavaScript中的Objects, Prototypes和Classes
【摘要】 日常逛街(一个基于kendoUI的文档在线编辑浏览审核发布管理的网站)看看代码,看到一段代码,很怀念的感觉,最近都不怎么见到这么写的了,可能是用多了npm install了的原因吧...(类似的这种https://github.com/inolen/quakejs/blob/master/lib/directed-graph.js写法)function CommonClassA(){ thi...
日常逛街(一个基于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
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)