Author's note: The basic knowledge triggered by a sentence is restored. If the foundation is not solid, what else do you need to do?
Recently, when I was reading some articles on React, I saw a question like this, "Why do super have to be written in every class? What does super do?" When I first saw this question, I directly thought of the manifestation of inheritance behavior in JavaScript. The author's sentence later, "super cannot be omitted, if omitted, it will cause an error." At that time, an idea popped up in my mind, was this classmate writing something wrong? Isn't super just used to call the parent class constructor and hang the instance attributes of the parent class on this? Why does it still cause an error if you don’t write it?
Later, I wrote a demo myself and tried it. There was a real error. What went wrong? I found Teacher Ruan’s tutorial and opened it and read it carefully. I found that there was such a sentence in it:
The subclass must call the super method in the constructor method, otherwise an error will be reported when creating a new instance. This is because the subclass's own this object must be shaped first through the constructor of the parent class, obtain the same instance attributes and methods as the parent class, and then process them, and add the subclass's own instance attributes and methods. If the super method is not called, the subclass will not get this object.
So that's the way this object is constructed in ES6 has changed.
Inheritance in ES5
// Shape - Superclassfunction Shape() { = 0; = 0; } // Methods of parent class = function(x, y) { += x; += y; ('Shape moved.'); }; // Rectangle - Subclass (subclass)function Rectangle() { (this); // call super constructor. } // Subclass continues to inherit the parent class = (); = Rectangle; var rect = new Rectangle(); ('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true ('Is rect an instance of Shape?', rect instanceof Shape); // true (1, 1); // Outputs, 'Shape moved.'
As shown above: An example of implementing single inheritance in ES5 is shown. In the book "Advanced Programming of Javascript", this inheritance method is defined as "parasitic combined inheritance". No matter what form or naming, implementing inheritance in ES5 always requires one principle: put instance attributes in the constructor and hang them on this, hang some method attributes on the prototype object, and subclasses can be shared. The key to the above inheritance method is two points:
- The subclass constructor runs the parent class constructor by applying or call, which hangs the instance attribute of the parent class on this object of the subclass.
- Based on the prototype object of the parent class, a prototype chain relationship is established between the prototype object of the child class and the prototype object of the child class. It is used, and the essence is .__proto === ;
Inheritance in ES6
class Point { constructor(x, y) { = x; = y; } toString() { return '(' + + ', ' + + ')'; } } class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // Call the constructor(x, y) of the parent class = color; } toString() { return + ' ' + (); } }
Inheritance in ES6 uses the extends keyword, and function has also become the class keyword. The essence of class is still a syntactic sugar, and everyone will blurt out this, but in the inheritance mechanism, let’s take a look at how babel translates it for us here.
var ColorPoint = /*#__PURE__*/ function (_Point) { _inherits(ColorPoint, _Point); function ColorPoint(x, y, color) { var _this; _classCallCheck(this, ColorPoint); _this = _possibleConstructorReturn(this, _getPrototypeOf(ColorPoint).call(this, x, y)); // Call the constructor(x, y) of the parent class _this.color = color; return _this; } _createClass(ColorPoint, [{ key: "toString", value: function toString() { return + ' ' + _get(_getPrototypeOf(), "toString", this).call(this); } }]); return ColorPoint; }(Point);
As mentioned above, the code translated by babel, there are several key points:
1. _inherits()
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } = (superClass && , { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
First, complete the verification of the extends object. It must be function or null, otherwise an error will be reported. Next, complete the following:
ColorPoint.__proto__ === Point; .__proto__ === ;
2. In the ColorPoint constructor _classCallCheck() and _possibleConstructorReturn()
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
It is mainly used to detect that the constructor cannot be called directly, but must be called through new.
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
Call the constructor of the parent class, initialize some instance properties, and return this. Use the returned this to assign the value to the subclass this object. The subclass returns this object through this step, and then add some instance attributes on this basis.
This is the biggest difference. If you do not go through this step, the subclass does not have this object, and an error will be reported once you operate a non-existent this object.
3. _createClass()
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
The last step is to mount the prototype attribute and the static attribute. If it is a prototype attribute, it is hung on the prototype on the Constructor. If it is a static attribute or a static method, it is hung on the Constructor.
Summarize
Basic knowledge must be laid out, not for interviews. If you don’t work in the early stage, many things will become ambiguous later. When others ask, they will be "possible" and "maybe". How can you reach a thousand miles without taking a single step? Come on.
Reference link
/#docs/class-extends
/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&targets=&browsers=&builtIns=false&debug=false&code_lz=Q
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.