JavaScript中的Objects, Prototypes和Classes

网友投稿 497 2022-05-29

日常逛街(一个基于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();

感觉和直接这么写也没什么区别:

JavaScript中的Objects, Prototypes和Classes

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小时内删除侵权内容。

上一篇:别死写代码,这 25 条比涨工资都重要
下一篇:如何电脑上共享代码
相关文章