Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

preface

What is new?

The new operator creates an instance of a user-defined object type or one of the built-in object types with a constructor.

While the definition is somewhat obscure, let’s take a look at a concrete example to see what new can do in JavaScript.

For example

// You can't be thin in real life, but you should stay slim online
function Thin_User(name, age) {
    this.name = name;
    this.age = age;
}

Thin_User.prototype.eatToMuch = function () {
    // Daydreaming
    console.log('i eat so much, but i\'m very thin!!! ');
}

Thin_User.prototype.isThin = true;

const xiaobao = new Thin_User('zcxiaobao'.18);
console.log(xiaobao.name);   // zcxiaobao
console.log(xiaobao.age);    / / 18
console.log(xiaobao.isThin); // true
// i eat so much, but i'm very thin!!!
xiaobao.eatToMuch(); 
Copy the code

Xiaobao can:

  • Access the constructorThin_UserIn the attribute
  • Access to theThin_User.prototypeIn the attribute

To put it more bluntly, New did these things:

  • Creates an empty object, object of__proto__->Thin_User.prototype
  • Executes the constructor and willthisPoint to a new object
  • Return a new object

To construct a function using new, perform the following four operations:

  1. Create an empty simpleJavaScriptThe 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

added

Since new is a keyword, we can’t override it like we can override higher-order arrays, so we’ll write a function createObject that mimics the effect of new. The specific usage is as follows:

function Thin_User(name, age) {}

const u1 = new Thin_user(...)
constu2 = createObject(Thin_User, ... a)Copy the code

A preliminary simulation

CreateObject createObject

  • Create a new objectobj
  • Set up theobj.__proto__->constructor.prototype (But JavaScript does not recommend direct modificationprotoProperty, which provides setPrototypeOf methods to modify stereotypes specifically)
  • useconstructor.call/apply(obj, ...), add the property toobj
  • returnobj

__proto__ and prototype, you can see the full understanding of JavaScript prototype and prototype chain call/apply, you can see [JavaScript hand rip call, apply]juejin.cn/post/702094…

With that done, we can write the first version of the new code:

function createObject(Con) {
    // Create a new object obj
    // var obj = {}; Can also be
    var obj = Object.create(null);

    // put the obj.__proto__ -> constructor prototype
    // (not recommended)obj.__proto__ = con.prototype
    Object.setPrototypeOf(obj, Con.prototype);

    // Execute the constructor
    Con.apply(obj, [].slice.call(arguments.1));

    // Return a new object
    return obj;
}
Copy the code

Return value processing

If a constructor returns a value, what will be the result of new?

The return value is a primitive type

Assuming that the constructor returns a primitive type, let’s look at the result:

function Thin_User(name, age) {
    this.name = name;
    this.age = age;
    return 'i will keep thin forever';
}

Thin_User.prototype.eatToMuch = function () {
    console.log('i eat so much, but i\'m very thin!!! ');
}

Thin_User.prototype.isThin = true;

const xiaobao = new Thin_User('zcxiaobao'.18);
console.log(xiaobao.name);   // zcxiaobao
console.log(xiaobao.age);    / / 18
console.log(xiaobao.isThin); // true
// i eat so much, but i'm very thin!!!
xiaobao.eatToMuch(); 
Copy the code

Doesn’t the constructor do anything to the return value that seems to interfere with it?

No hurry, let’s go ahead and test the return value as an object.

The return value is an object

function Thin_User(name, age) {
    this.name = name;
    this.age = age;
    return {
        name: name,
        age: age * 10.fat: true
    }
}

Thin_User.prototype.eatToMuch = function () {
    // Daydream, leave fat tears
    console.log('i eat so much, but i\'m very thin!!! ');
}

Thin_User.prototype.isThin = true;

const xiaobao = new Thin_User('zcxiaobao'.18);
// Error: xiaobao.eatToMuch is not a function
xiaobao.eatToMuch();
Copy the code

When I performeatToMuch“, the console reported an error with no current function, so I printed itxiaobaoObject:

The xiaobao object ‘s age has been changed and the fat attribute has been added, which is exactly the same as the return value of the constructor.

After looking at these two examples, it is almost clear that the constructor returns a value: when the constructor returns an object, the object is returned directly.

Final version of the simulation

function createObject(Con) {
    // Create a new object obj
    // var obj = {}; Can also be
    var obj = Object.create(null);

    // put the obj.__proto__ -> constructor prototype
    // (not recommended)obj.__proto__ = con.prototype
    Object.setPrototypeOf(obj, Con.prototype);

    // Execute the constructor and accept the constructor return value
    const ret = Con.apply(obj, [].slice.call(arguments.1));

    // If the constructor returns an object, the object is returned
    // Otherwise return obj
    return typeof(ret) === 'object' ? ret: obj;
}
Copy the code

Past wonderful articles

  • Cow guest latest front-end JS written test 100 questions
  • Native JavaScript soul torture (2), can you answer all correctly?
  • Native JavaScript soul Test (1), how much can you answer?
  • A thorough understanding of prototypes and prototype chains in JavaScript
  • JavaScript precompilation learning
  • Complete understanding of EventLoop in JavaScript
  • “2W word big chapter 38 interview questions” completely clear JS this pointing to the problem

After the language

If you feel that this article has some help for you, I hope you can point a like, encourage and encourage bag, bag will continue to work hard. In addition, if this article has a question, or do not understand part of the article, you can reply to me in the comment section, we come to discuss, learn together, progress together!

If you feel confused in the comments section, you can also add my wechat or QQ for detailed communication, and the name is battlefield small bag.