未加星标

A matter of class ― examining the class construct in JavaScript

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

This article was originally published on my Medium profile

It is more than one year and half since the class construct has become part of the official javascript syntax. Introduced by the ECMAScript 2015 specifications, this construct has been enthusiastically welcomed by many developers. Indeed, it has been considered a sign of the formalization of various attempts to simulate classes, inheritance and other Object-Oriented features offered for several years by many libraries, such as Prototype , ExtJS , Dojo , Backbone , Ember and others. TypeScript itself was born with the aim of bringing the class-based Object-Oriented programming in JavaScript language. However the class construct may lead to serious misconceptions about the Object-Oriented nature of JavaScript. Let’s analyze why.

A convenient construct

Using the class construct is very handy. Just take a look at the following code to define the Animal class:

class Animal { constructor(name, legsNumber) { this.name = name; this.legsNumber = legsNumber; } speak() { console.log(this.name + ‘ makes a noise.’); } }

Now let’s compare it with the equivalent ECMAScript 5 code:

var Animal = function (name, legsNumber) { this.name = name; this.legsNumber = legsNumber; }; Animal.prototype.speak = function() { console.log(this.name + ‘ makes a noise.’); };

The class construct provides a much more compact code. It appears self-contained and familiar to people who have a traditional Object-Oriented programming background.

The convenience of this construct becomes even more noticeable when we use inheritance, as we can see by analyzing the following code where the Snake and Horse classes are defined by deriving from Animal :

class Snake extends Animal { constructor(name: string) { super(name, 0); } speak() { console.log(this.name + ‘ hisses.’); } } class Horse extends Animal { constructor(name: string) { super(name, 4); } speak() { console.log(this.name + ‘ whinnies.’); } }

Let’s consider now the respective definitions with the dear old ECMAScript 5:

var Snake = function (name) { Animal.apply(this, [name, 0]); }; Snake.prototype = Object.create(Animal.prototype); Snake.prototype.constructor = Snake; Snake.prototype.speak = function() { console.log(this.name + ‘ hisses.’); }; var Horse = function (name) { Animal.apply(this, [name, 4]); }; Horse.prototype = Object.create(Animal.prototype); Horse.prototype.constructor = Horse; Horse.prototype.speak = function() { console.log(this.name + ‘ whinnies.’); };

The convenience of using the class construct seems clear: in addition to a smaller number of statements we get a greater readability and a similarity to the syntax of most Object-Oriented programming languages. Anyway, regardless of the definition used, in both cases we will use the classes and constructor functions in the same way:

var kaa = new Snake(“Kaa the python”); var fury = new Horse(“Fury the Horse”); console.log(kaa.legsNumber); //0 console.log(fury.legsNumber); //4

This ensures the maximum interoperability between the old and the new approach.

Not everyone is happy

Despite its convenience, however, not all developers are so excited about the introduction of the class construct. It looks familiar to most programmers, and gives the illusion of using a class-based Object-Oriented programming language such as Java and C #.

But that is the whole point: it is an illusion, a dangerous illusion. Contrary to what might seem, ECMAScript 2015 specifications have not introduced the concept of class in JavaScript. JavaScript is and remains a prototype-based Object-Oriented programming language, even with the class construct.

The introduction of this construct in JavaScript syntax seems to extend the chain of errors that characterized the definition of this language: from the choice of the name itself, that has caused (and still causes) a bit of confusion with Java, to the use of the new keyword to create objects, actively contested by Douglas Crockford .

The main effect of these choices is that programmers are misguided in the real understanding of the language and are led to blame it because its behavior is not what expected.

Is it a real class?

But what is the difference between the class construct in class-based languages and the one in JavaScript? As we said, JavaScript is still a prototype-based language, so the class construct is just syntactic sugar for creating constructor functions in a more compact way. If we try to get the type of a class, we will find that it is not but a function:

console.log(typeof Animal); //function

The definition of Animal , Snake and Horse by using the class construct has the same effect of its definition by using the old ECMAScript 5-style code. Objects are not created by referencing a class, but by referencing a prototype, that is another object, as usual in JavaScript. This means that we can dynamically change the structure of our objects without involving its original class. For example, we can write the following code:

fury.wingsNumber = 2; console.log(fury instanceof Horse); //true

We add a couple of wings to our Horse object, and it continues to be a horse. That’s perfectly legal in JavaScript, but it is very difficult to implement and to understand in a class-based world.

Even worst, we can overturn the whole structure of our Horse object as follows:

var furySnake = new Horse(); furySnake.legsNumber = 0; furySnake.speak = function() { console.log(this.name + ‘ hisses.’); };

We have redefined the structure of a Horse like if it was a Snake , but it still remains an instance of the Horse class.That’s out of any definition of class, not only in the context of programming languages, but also in philosophy and set theory contexts.

For example, from a mathematical point of view, a class is a collection of objects that can be unambiguously defined by one or more properties that all its member share. Clearly, since fury and furySnake share no properties, they cannot belong to the same (conceptual) class. Also from a class-based Object Oriented point of view the two objects can’t belong to the same class.

Conclusion

Maybe the choice of a name other than class would have sounded strange to developers coming from languages like Java, C# and C++, but it would have created fewer illusions and disappointments.

In any case, now the die is cast. The important thing is that the JavaScript developer is aware of what class really means. You have been warned…

Andrea Chiarelli is the author of Mastering JavaScript Object Oriented Programming (Packt Publishing).

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:A matter of class ― examining the class construct in JavaScript
本站链接:http://www.codesec.net/view/534219.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(37)