kind
Classes are templates for creating objects. The method of generating object instances in JavaScript is through the constructor, which is quite different from mainstream object-oriented languages (java, C#) in writing, as follows:
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 1);
ES6 provides a way of writing closer to the Java language, introducing the concept of Class as a template for objects. Through the class
keyword, you can define a class.
As follows: constructor()
is the construction method, and this
represents the instance object:
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
The data type of the class is the function, which itself is the constructor that points to the function:
// ES5 函数声明
function Point() {
//...
}
// ES6 类声明
class Point {
//....
constructor() {
}
}
typeof Point // "function"
Point === Point.prototype.constructor // true
The method defined in the class is linked to Point.prototype
, so the class only provides syntactic sugar, and the essence is the prototype chain call.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
Point.prototype = {
//....
toString()
}
var p = new Point(1, 1);
p.toString() // (1,1)
Another way to define a Class expression
// 未命名/匿名类
let Point = class {
constructor(x, y) {
this.x = x;
this.y = y;
}
};
Point.name // Point
There is an important difference between function declarations and class declarations. Function declarations will be promoted, while class declarations will not be promoted.
let p = new Point(); // 被提升不会报错 function Point() {} let p = new Point(); // 报错,ReferenceError class Point {}
constructor()
constructor()
method is the default method of the class. new
will automatically call this method when the instance object is generated.
A class must have the constructor()
method. If it is not explicitly defined, the engine will add an empty constructor()
by default.
constructor()
method returns the instance object by default (ie this
).
class Point {
}
// 自动添加
class Point {
constructor() {}
}
getter and setter
get
and set
can be used inside the class to set the value function and the value function of a certain attribute to intercept the access behavior of the attribute.
class User {
constructor(name) {
this.name = name;
}
get name() {
return this.name;
}
set name(value) {
this.name = value;
}
}
this
this
inside the method of the class, it defaults to the instance of the class. When calling this
, you need to use the obj.method()
method, otherwise an error will be reported.
class User {
constructor(name) {
this.name = name;
}
printName(){
console.log('Name is ' + this.name)
}
}
const user = new User('jack')
user.printName() // Name is jack
const { printName } = user;
printName() // 报错 Cannot read properties of undefined (reading 'name')
If you want to call it alone without bind(this)
an error, a method can be called 06177612b7055b in the constructor.
class User {
constructor(name) {
this.name = name;
this.printName = this.printName.bind(this);
}
printName(){
console.log('Name is ' + this.name)
}
}
const user = new User('jack')
const { printName } = user;
printName() // Name is jack
bind(this)
will create a new function and use the incomingthis
as the context of the function when it is called.
You can also use arrow functions, because the this
inside the arrow function always points to the object where it was defined.
class User {
constructor(name) {
this.name = name;
}
printName = () => {
console.log('Name is ' + this.name)
}
}
const user = new User('jack')
const { printName } = user;
printName() // Name is jack
Static properties
Static attributes refer to the attributes of the class itself, not the attributes defined on the instance object this
.
class User {
}
User.prop = 1;
User.prop // 1
Static method
You can define a static method in the class, the method will not be inherited by the object instance, but directly through the class to call.
The use of this
in the static method refers to the class.
class Utils {
static printInfo() {
this.info();
}
static info() {
console.log('hello');
}
}
Utils.printInfo() // hello
Regarding the limitation of the calling range of the method, such as: private public, ES6 does not provide it for the time being, it is generally through an agreement, such as: adding an underscore _print()
in front of the method to indicate a private method.
inherit
In Java, class inheritance extends
ES6 classes can also be inherited extends
When inherited, the subclass must constructor
call method super
method, otherwise it will error when creating a new instance.
class Point3D extends Point {
constructor(x, y, z) {
super(x, y); // 调用父类的constructor(x, y)
this.z = z;
}
toString() {
return super.toString() + ' ' + this.z ; // 调用父类的toString()
}
}
The static methods of the parent class will also be inherited by the child class.
class Parent {
static info() {
console.log('hello world');
}
}
class Child extends Parent {
}
Child.info() // hello world
super keyword
The constructor of the subclass must execute the super
function once, which represents the constructor of the parent class.
class Parent {}
class Child extends Parent {
constructor() {
super();
}
}
When calling the method of the parent class super
ordinary method of the this
inside the method points to the current instance of the subclass.
class Parent {
constructor() {
this.x = 1;
this.y = 10
}
printParent() {
console.log(this.y);
}
print() {
console.log(this.x);
}
}
class Child extends Parent {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}
let c = new Child();
c.printParent() // 10
c.m() // 2
_proto_
and prototype
When you first _proto_
JavaScript, 06177612b709ba and prototype
are easy to confuse. First of all, we know that each JS object corresponds to a prototype object, and inherits properties and methods from the prototype object.
prototype
some built-in objects and functions. It is a pointer to an object. The purpose of this object is to include the properties and methods shared by all instances (we call this object the prototype object)._proto_
Each object has this attribute, which generally points to theprototype
attribute of the corresponding constructor.
The picture below shows some built-in objects prototype
According to the above description, look at the following code
var obj = {} // 等同于 var obj = new Object()
// obj.__proto__指向Object构造函数的prototype
obj.__proto__ === Object.prototype // true
// obj.toString 调用方法从Object.prototype继承
obj.toString === obj.__proto__.toString // true
// 数组
var arr = []
arr.__proto__ === Array.prototype // true
For function objects, each function declaration also has prototype
and __proto__
properties, object properties created __proto__
point function prototype
, function __proto__
in turn points to the built-in function object (Function) of prototype
.
function Foo(){}
var f = new Foo();
f.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Inheriting __proto__
Class as a syntactic sugar for the constructor, there will also be prototype
attributes and __proto__
attributes, so there are two inheritance chains at the same time.
__proto__
attribute of the subclass indicates the inheritance of the constructor and always points to the parent class.- The
prototype
attribute of the__proto__
attribute indicates the inheritance of the method and always points to theprototype
attribute of the parent class.
class Parent {
}
class Child extends Parent {
}
Child.__proto__ === Parent // true
Child.prototype.__proto__ === Parent.prototype // true
Inherit the __proto__
__proto__
attribute of the subclass instance prototype
subclass construction method.
Examples of subclass __proto__
attribute __proto__
attributes, points to the parent class instance __proto__
properties. In other words, the prototype of the prototype of the child class is the prototype of the parent class.
class Parent {
}
class Child extends Parent {
}
var p = new Parent();
var c = new Child();
c.__proto__ === p.__proto__ // false
c.__proto__ === Child.prototype // true
c.__proto__.__proto__ === p.__proto__ // true
summary
Class in JavaScript is more syntactic sugar, and essentially cannot bypass the prototype chain. Welcome everyone to leave a message and exchange.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。