Preface:

This article will take you step by step to understand how to write new functions by hand in a simple and logical way.

First throw the final version of the new function, if you do not understand, please be sure to follow me to see! There must be something! (ఠ e ఠ) Blue!!

function myNew(Fn) { if (typeof Fn ! = = 'function' | | Fn = = = null) throw new TypeError (' This is not a constructor ') / / calibration var args = Fn Array.from(arguments).slice(1) var obj = {} // 1 Create an empty simple JavaScript object (i.e. '{}') obj.__proto__ = Fn. Prototype // 2. Add the attribute '__proto__' to the object created in Step 1 and link it to the prototype object of the constructor var res = fn.call (obj,... Args) // 3. Pass the new object created in Step 1 as the context for this; return Object(res) === res ? Res: obj // 4. If the function returns no object, return this. }Copy the code
new

In a word: Instantiate constructors.

The new keyword does the following:

  1. Create an empty simple JavaScript object (i.e {} );
  2. Add attributes to the object created in Step 1 __proto__ Link this property to the constructor’s prototype object;
  3. Take the object created in Step 1 as the objectthisContext;
  4. Returns if the function does not return an objectthis.

The above four points are the description of new on MDN, which can be written in accordance with the above four steps

1. The first edition of new
function myNew1(Fn) { var obj = {} // 1. Create an empty simple JavaScript object (i.e. '{}') obj.__proto__ = Fn. Prototype // 2. Add an attribute '__proto__' to the object created in Step 1, linking it to the constructor's prototype object; Var res = fn.call (obj) // 3. Use the object created in Step 1 as the context for this. return res ? Res: obj // 4. If the function returns no object, return this. } var Fn = function(name, {this.name = name this.age = age} Fn.prototype.say = function() {console.log('Fn.prototype.say') newObj = myNew1(Fn) newObj // Fn {name: undefined, age: undefined} newObj.say() // Fn.prototype.say var newObj1 = new Fn() newObj1 // Fn {name: undefined, age: undefined} newObj1.say() // Fn.prototype.sayCopy the code

Ok, end of article!

However, it seems that things are not so simple 😂

  1. newCan pass to participate
  2. Fn functionCheck problem
  3. ifFn functionWhat about internal returns

Please follow me on with the questions

2. Version 2 New
Function myNew2(Fn) {var args = array.from (arguments).slice(1) var obj = {} // 1 Create an empty simple JavaScript object (i.e. '{}') obj.__proto__ = Fn. Prototype // 2. Add the attribute '__proto__' to the object created in Step 1 and link it to the prototype object of the constructor var res = fn.call (obj,... Args) // 3. Pass the new object created in Step 1 as the context for this; Return res // 4. If this function does not return an object, return this. } var Fn = function(name, {this.name = name this.age = age} Fn.prototype.say = function() {console.log('Fn.prototype.say') newObj = myNew2(Fn, 'Leo', 18) newObj // Fn {name: 'Leo', age: 18} newObj.say() // Fn.prototype.say var newObj1 = new Fn('Leo', 18) newObj1 // Fn {name: 'Leo', age: Function myNew2(Fn) {if (typeof Fn! == 'function' || Fn === null) throw new TypeError('this is not a constructor') var args = Array.from(arguments).slice(1) Var obj = {} // 1. Create an empty simple JavaScript object (i.e. '{}') obj.__proto__ = Fn. Prototype // 2. Add the attribute '__proto__' to the object created in Step 1 and link it to the prototype object of the constructor var res = fn.call (obj,... Args) // 3. Pass the new object created in Step 1 as the context for this; Return res // 4. If this function does not return an object, return this. } var newObj = myNew2(1, 'Leo', 18) // uncaught TypeError: this is not a constructor var Fn = 1 var newObj1 = new Fn('Leo', 18) // Uncaught TypeError: Function myNew2(Fn) {if (typeof Fn! == 'function' || Fn === null) throw new TypeError('this is not a constructor') var args = Array.from(arguments).slice(1) Var obj = {} // 1. Create an empty simple JavaScript object (i.e. '{}') obj.__proto__ = Fn. Prototype // 2. Add the attribute '__proto__' to the object created in Step 1 and link it to the prototype object of the constructor var res = fn.call (obj,... Args) // 3. Pass the new object created in Step 1 as the context for this; return Object(res) === res ? Res: obj // 4. If the function returns no object, return this. } var Fn = function(name, Age) {enclosing name = name this. Age = age return 1 / / return here is object (null/undefined/number/string/boolen)} Fn. Prototype. Say = Function () {console.log(' fn.prototype. say')} var newObj = myNew2(Fn, 'Leo', 18) newObj = myNew2(Fn, 'Leo', 18) 18} newObj.say() // Fn.prototype.say var newObj1 = new Fn('Leo', 18) newObj1 // Fn {name: 'Leo', age: 18} newObj1.say() // Fn.prototype.say var Fn = function(name, {this.name = name this.age = age return {} Fn. Prototype. say = function() { Console. log(' fn.prototype. say')} var newObj = myNew2(Fn, 'Leo', 18) newObj // Fn {} newObj.say() // Uncaught TypeError: newObj.say is not a function var newObj1 = new Fn('Leo', 18) newObj1 // Fn {} newObj1.say() // Uncaught TypeError: newObj.say is not a function var Fn = function(name, Age){this.name = name this.age = age return function cbFn(){} Function () {console.log(' fn.prototype. say')} var newObj = myNew2(Fn, ƒ cbFn(){} newobj.say () // Uncaught TypeError: Description newobj. say is not a function var newObj1 = new Fn('Leo', 18) newObj1 // ƒ cbFn(){} newobj1. say() // Uncaught TypeError: newObj.say is not a functionCopy the code

This is the end of the simulation of new

Final output:

function myNew(Fn) { if (typeof Fn ! = = 'function' | | Fn = = = null) throw new TypeError (' This is not a constructor ') / / calibration var args = Fn Array.from(arguments).slice(1) var obj = {} // 1 Create an empty simple JavaScript object (i.e. '{}') obj.__proto__ = Fn. Prototype // 2. Add the attribute '__proto__' to the object created in Step 1 and link it to the prototype object of the constructor var res = fn.call (obj,... Args) // 3. Pass the new object created in Step 1 as the context for this; return Object(res) === res ? Res: obj // 4. If the function returns no object, return this. }Copy the code

Related knowledge:

  • apply/call
  • Object type correlation
  • Prototype chain correlation
The last

Original is not easy to hope that we support a lot, welcome to clap brick!

Related articles recommended

  • Interviewer series: Please write an anti – shake or throttle function debounce/throttle
  • 5 minutes quick handwriting implementation: Call /apply
  • 5 minutes quick handwriting implementation: bind