The use of New

preface

I think most people, look at the article is purposeful, may want to figure out the doubts in the heart, and then start Baidu.

Without further discussion, we look at this article on the new operator in javascirpt with a few questions in mind, and finally figure them out.

  • How to use new?
  • What does the inner constructor do when new creates an object?
  • How does the object created by new relate to the prototype of the constructor and the prototype chain?
  • What is the priority of this in the corresponding constructor relative to other ways of binding this?

How to use new

Let’s test the following code

const a = 1
const b = 'ab'
const c = null
const d = undefined
const e = true
const f = function () {}
const g = {}

console.log(new a)
console.log(new b)
console.log(new c)
console.log(new d)
console.log(new e)
console.log(new f())
console.log(new g)

Copy the code

Console. log(new f()) prints an object. TypeError: g is not a constructor. So new is easy to use, and it’s followed by a function, which we’ll call a constructor.

One of them:

console.log(new f())
console.log(new f)
Copy the code

There is no difference in execution; new automatically executes the following constructor. When the constructor has no arguments, the two can be equivalent.

What does the inner constructor do when new creates an object

Let’s summarize this by executing code:

function Person() {
    console.log('Person constructor')}console.log(new Person())
Copy the code

Print:

The person constructor person {}Copy the code

As we can see from the print, when new:

  1. The constructor is executed
  2. An empty object is now returned

Ok, proceed to test:

function Person() {
    this.name = 'With fashion sauce'
    this.logname = function () {
        console.log(this.name); }}const p = new Person()

console.log(p) // Person {name: 'name ', logname: [Function (anonymous)]}
Copy the code

One thing we can conclude from this test is that the constructor’s this is bound to the object returned.

Let’s look at the relationship between the returned object and the constructor prototype:

function Person() {
}
Person.prototype = {
    name: 'With fashion sauce'.logname: function() {
        console.log(this.name); }}const p = new Person()

console.log(Object.getPrototypeOf(p)) // {Function: logname, logname: [Function: logname]}
console.log(p) / / {}
p.logname() // Follow the fashion sauce
Copy the code

As we know, the new object inherits the constructor’s prototype, but does not assign a value to that object, that is, P.__proto__ === Person.prototype.

The last case:

function Animal() {
    this.n = 'With fashion sauce'
    this.l = function () {
        console.log(this.name);
    }
}
Animal.prototype = {
    b: 'b'
}

function Person() {
    this.name = 'With fashion sauce'
    this.logname = function () {
        console.log(this.name);
    }
    console.log('Executed')
    return new Animal()
}
Person.prototype = {
    name: 'With fashion sauce'.logname: function() {
        console.log(this.name); }}const p = new Person()

console.log(Object.getPrototypeOf(p)) // { b: 'b' }
console.log(p) // l: [Function (anonymous)]}
Copy the code

When the constructor returns a value, we know that the new object created is directly that object, this does not refer to that object, and the prototype of the object refers directly to Animal’s prototype, i.e. the object created by New Animal.

Conclusion:

  1. New can only be followed by a constructor
  2. Constructor internal code is executed
  3. The constructor creates a new object if the return value type is not an object, and the inner this points to the object, and the prototype of the object points to the constructor prototype.
  4. If the constructor returns an object, it returns the object directly, containing the prototype of the object.

Write a new

const _new = function (ConFunc, ... args) {
  	if (typeofConFunc ! = ='function') {throw 'must is not a constructor'
    }
    const a = {}
    const res = ConFunc.apply(a, args)
    a.__proto__ = ConFunc.prototype
    return typeof res === 'object' ? res : a;
}
Copy the code

Simple handwriting implementation.

We can test the priority of this in new, and we can directly tell the conclusion: New has the highest priority, compared to other changes in this direction. This is explained in detail in my other article. The orientation and principle of this