Author: Fernando Doglio
Translator: Frontend Xiaozhi
Source: meidum
thumbs look , micro-channel search [ big move in the world ] , B station concerned [ the front end of a small intellectual ] this background there is no giant, but with an upward positive attitude of people. This article GitHub
https://github.com/qq449245884/xiaozhi has been included, the article has been classified, and a lot of my documents and tutorial materials have been sorted out.
It's not that there is a problem with JS classes, but if you have been using the language for a while, especially ES5, then you may know the evolution from prototypal inheritance to the current class model.
What's wrong with the prototype chain?
In my humble opinion, the answer to this question is: does not have . But it took many years for the community to class concept into different structures and libraries, so the ECMA technical committee decided to add it anyway.
You would ask, is there any problem with this? This is what they really do, add some composition on top of the prototypal inheritance we already have, and decide to call it class , which in turn makes developers think they We are dealing with an object-oriented language, when in fact they are not.
Classes are nothing but syntactic sugar
jS does not have full OOP support, it never has, because it never needs it.
On the surface, the current version of the class shows the OOP paradigm because:
- We can create basic class definitions and group states and behaviors together in a very classic syntax.
- We can inherit from one class to another.
- We can define the visibility of properties and methods between public and private (although private fields are still an experimental feature).
- We can define
getter
andsetter
for attributes. - We can instantiate the class.
So why do I say that classes are syntactic sugar? Because although they look very object-oriented on the surface, if we try to do something beyond them, such as defining one class to extend two classes (currently impossible Thing), we need to use the following code
// 辅助函数
function applyMixins(derivedCtor, baseCtors) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
let descriptor = Object.getOwnPropertyDescriptor(baseCtor.prototype, name)
Object.defineProperty(derivedCtor.prototype, name, descriptor);
});
});
}
class A {
methodA () {
console.log('A')
}
}
class B {
methodB () {
console.log('B')
}
}
class C {
}
// 使用 mixins
We need to do this because we cannot write in JS:
class A {
methodA(){
console.log("A")
}
}
class B {
methodB(){
console.log("B")
}
}
class C extends A, B {
}
In the above example, the key part should be the function applyMixins
If, you don't fully understand what it is trying to do, but you can clearly see that it is accessing the prototype properties of all classes to copy and redistribute methods and properties. This is where we need to see the truth: classes are nothing but syntactic sugar on top of the proven prototypal inheritance model.
Does this mean that we should stop using classes? Of course not, the important thing is to understand it, and if we want to break through the limitations of the class, then we have to deal with it with prototypes.
What is missing in the OOP model of JS?
If our current OOP model is so thin, it is only an abstraction layer of prototypal inheritance, then what are we missing? What makes JS truly OOP?
A good way to look at this question is to look at what TypeScript is doing. The team behind the language has undoubtedly pushed JS to its limit by creating something that can be translated into JS. This in turn limits their capabilities.
Some OOP constructs currently missing in JS have built-in type checking functions and have no real meaning in dynamically typed languages. This may be the reason why they have not been added.
interface
Interfaces help define the API that the class should follow. One of the main benefits of interfaces is that we can define variables of any class that implements the same interface, and then safely call any of its methods.
interface Animal {
speak()
}
class Dog implements Animal{
speak() {
console.log("Woof!")
}
}
class Cat implements Animal{
speak() {
console.log("Meau!")
}
}
class Human implements Animal{
speak() {
console.log("Hey dude, what's up?")
}
}
//如果我们在JS中有接口,我们可以放心地做:
let objects = [new Dog(), new Cat(), new Human()]
objects.forEach(o => o.speak())
Of course, we can speak
method and overriding its class, but the interface is more clear and elegant.
Abstract class
Whenever I try to perform a complete OOP operation on my code, I definitely miss the abstract class in JS. An abstract class is a class that defines and implements methods, but it is never instantiated. This is a way of grouping common behaviors that can be extended but never used directly. This is a great resource, and it can definitely be implemented in the current JS field without spending too much effort.
Static polymorphism
Static polymorphism allows us to define the same method multiple times in the same class, but with different signatures. In other words, repeat the name, but make sure it receives different parameters. Now we have the rest
parameter of JS, which allows us to have an arbitrary number, but it also means that we must add additional code to the method to handle this dynamic. On the contrary, we can distinguish method signatures more clearly, and we can directly encapsulate different meanings of the same behavior into different methods.
The version on the left is not valid JS, but it provides a cleaner code, so it is easier to read and understand. The version on the right is completely valid, it is relatively difficult to read, and it needs to understand some ES6 syntax.
Polymorphism is usually achieved by looking at the types of parameters received in the method. However, due to the working principle of JS, we know this is impossible.
Protected properties and methods
We already have public visibility, and we soon have private visibility of methods and properties (via the # prefix). I think the next step should be to add protected visibility. However, not yet. I think all three are necessary if you want a proper OOP experience. Protected properties and methods can only be accessed from within the class or one of its subclasses (in contrast to private visibility, which restricts access to only the parent class).
I’m sharing it with you today, I’m Xiaozhi, and we’ll see you in the next issue.
possible bugs after 1612d7810c1577 code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .
Original: https://blog.bitsrc.io/whats-wrong-with-javascript-s-classes-3378c73205af
comminicate
The article is continuously updated every week, and you can search for "Great Move World" on WeChat to read and update it as soon as possible (one or two earlier than the blog). This article has been included on https://github.com/qq449245884/xiaozhi I have sorted out a lot of my documents, welcome to Star and improve it. You can refer to the test site for review for interviews. In addition, pay attention to the account, and reply to 1612d7810c15d3 welfare background, you can see the benefits, you know.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。