The original intention of writing this series of articles is to "let every front-end engineer master high-frequency knowledge points to help work." This is the 18th cut of the front-end Hundred Topics. I hope that friends will pay attention to the public account "Kite-holder" and arm their minds with knowledge.
18.1 Basics
The role of new is to create an instance object through the constructor. The relationship between the instance, the prototype and the constructor is shown in the following figure:
18.2 What happened during the new process
What happens when the process of a constructor new? The brief overview is mainly divided into the following steps:
- A new object is created;
- The __proto__ attribute of the object points to the prototype of the constructor, namely Fn.prototype;
- Bind the execution context (this) to the newly created object;
- If the constructor has a return value (object or function), then this return value will replace the newly created object in the first step.
Did new really do these steps? Adhering to the principle of "practice is the only criterion for testing truth", the following will verify these key points one by one.
function Fun() {
this.a = 10;
this.b = 20;
this.method1 = () => {
return this.a + this.b;
}
this.method2 = () => {
return this;
}
}
Fun.prototype = {
method2: () => {
console.log('原型上的method1被访问');
}
}
18.2.1 Verification point 1-new object is created
Verification point 1 is that a new object is created. In fact, this has two meanings:
- The content returned after new is an object
const fun = new Fun();
console.log(fun); // { a: 10, b: 20, method1: [Function] }
console.log(typeof(fun)); // object
By printing its content and verifying by typeof, the returned content is indeed an object.
- Each time it returns is a newly created object
const fun1 = new Fun();
const fun2 = new Fun();
console.log(fun1 === fun2); // false
By creating two instances and judging that the two instances are not equal, it is proved that a new object is indeed returned each time.
18.2.2 Verification point 2-the object can access the properties and methods on the prototype
Verification point 2 is that the newly created instance can access the properties and methods on the prototype. To verify this key point, you only need to access the methods on the prototype. If the methods on the prototype can be accessed normally, it means that the verification point is passed and you are responsible. Fail.
const fun3 = new Fun();
fun3.method3(); // 原型上的method3被访问
Through verification, the methods on the prototype can indeed be accessed.
18.2.3 Verification point 3-this point
To verify the this point, you only need to print the this point.
const fun4 = new Fun();
console.log(fun4.method2()); // { a: 10, b: 20, method1: [Function], method2: [Function] }
console.log(fun4.method2() === fun4); // true
18.2.4 Verification point 4-the processing logic of the return value of the constructor
The return value of a function can have many kinds, such as: string, boolean, number, Object, function, etc. Let's verify some of the content below to see if the constructor has different return values and what values are the instances.
- The return value is string
function Fun() {
this.a = 10;
this.b = 20;
return 'test';
}
Fun.prototype = {
method: () => {
console.log('原型上的method被访问');
}
}
const fun = new Fun();
console.log(fun); // { a: 10, b: 20 }
Observe the final result, the string is not returned normally, the return value is a new instance.
- The return value is Object
function Fun() {
this.a = 10;
this.b = 20;
return {
c: 30
};
}
Fun.prototype = {
method: () => {
console.log('原型上的method被访问');
}
}
const fun = new Fun();
console.log(fun); // { c: 30 }
Observe the result, the return value is the object returned in the function, which means that when the constructor returns an object, the object will be returned, and the instantiated content will not be returned.
- The return value is function
function Fun() {
this.a = 10;
this.b = 20;
return function() {
this.d = 40;
};
}
Fun.prototype = {
method: () => {
console.log('原型上的method被访问');
}
}
const fun = new Fun();
console.log(fun); // [Function]
The effect of the returned function is the same as that of the returned object.
Through continuous attempts to summarize, the following conclusions can be drawn:
- The return value of the constructor is the basic type, and the return value is the instantiated object, which is not affected by the return value;
- The return value of the constructor is a reference type, and its return value is the return value after new.
18.3 Implement a new
After introducing so much, I have understood and verified what happened when new, so let's manually implement a new function of my own.
function myNew(Fn, ...args) {
// 一个新的对象被创建
const result = {};
// 该对象的__proto__属性指向该构造函数的原型
if (Fn.prototype !== null) {
Object.setPrototypeOf(result, Fn.prototype);
}
// 将执行上下文(this)绑定到新创建的对象中
const returnResult = Fn.apply(result, args);
// 如果构造函数有返回值(对象或函数),那么这个返回值将取代第一步中新创建的对象。
if ((typeof returnResult === 'object' || typeof returnResult === 'function') && returnResult !== null) {
return returnResult;
}
return result;
}
Small scale chopper
function Fun() {
this.a = 10;
this.b = 20;
}
Fun.prototype = {
method: () => {
console.log('原型上的method被访问');
}
}
const fun1 = new Fun();
console.log(fun1); // { a: 10, b: 20 }
const fun2 = myNew(Fun);
console.log(fun2); // { a: 10, b: 20 }
1. If you think this article is good, share it, like it, and let more people see it
2. Follow the official account holders, and kill the front-end 100 questions with the account owner
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。