The handwritten new operator

Pre-knowledge: Prototype, prototype chain (see understanding JS prototype, prototype chain and inheritance (see this if you can’t open it))

New operator

function MyConstructor () {
    this.data = "some data";
}
MyConstructor.prototype.getData = function(){
    console.log(this)
    return this.data
}

var instance1 = new MyConstructor()
console.log(instance1)
console.log(Object.prototype.toString.call(instance1))
console.log(instance1.getData())
console.log(instance1.__proto__ === MyConstructor.prototype)

var instance2 = new MyConstructor()
instance1.data = "another data"
console.log(instance1)
console.log(instance2)
instance1.getData()
instance2.getData()
console.log(instance2.__proto__ === instance1.__proto__)
Copy the code

We can see from the above example that we use the new operator when the constructor does not return:

  1. Get a new Object instance
  2. The instance method this refers to the instance itself
  3. Each instance’s __proto__ points to the constructor’s prototype object

When a constructor has a return, let’s test what the return instance and type looks like:

function test1(){
    this.data = "some data";
    return null
}
var t1 = new test1()
console.log(t1)
console.log(Object.prototype.toString.call(t1))
console.log(typeof null)

function test2(){
    this.data = "some data";
    return undefined
}
var t2 = new test2()
console.log(t2)
console.log(Object.prototype.toString.call(t2))
console.log(typeof undefined)

function test3(){
    this.data = "some data";
    return 0
    // return 1
}
var t3 = new test3()
console.log(t3)
console.log(Object.prototype.toString.call(t3))
console.log(typeof 0)

function test4(){
    this.data = "some data";
    return ' '
    // return '1'
}
var t4 = new test4()
console.log(t4)
console.log(Object.prototype.toString.call(t4))
console.log(typeof ' ')

function test5(){
    this.data = "some data";
    return false
    // return true
}
var t5 = new test5()
console.log(t5)
console.log(Object.prototype.toString.call(t5))
console.log(typeof false)

function test6(){
    this.data = "some data";
    return Symbol('s')}var t6 = new test6()
console.log(t6)
console.log(Object.prototype.toString.call(t6))
console.log(typeof Symbol('s'))

function test7(){
    this.data = "some data";
    return{}}var t7 = new test7()
console.log(t7)
console.log(Object.prototype.toString.call(t7))
console.log(typeof {})

function test8(){
    this.data = "some data";
    return function(){}}var t8 = new test8()
console.log(t8)
console.log(Object.prototype.toString.call(t8))
console.log(typeof function(){})

function test9(){
    this.data = "some data";
    return[]}var t9 = new test9()
console.log(t9)
console.log(Object.prototype.toString.call(t9))
console.log(typeof [])

function test10(){
    this.data = "some data";
    return new Date()}var t10 = new test10()
console.log(t10)
console.log(Object.prototype.toString.call(t10))
var date = new Date(a)console.log(typeof date)

function test11(){
    this.data = "some data";
    return /\s/
}
var t11 = new test11()
console.log(t11)
console.log(Object.prototype.toString.call(t11))
let reg =  /\s/
console.log(typeof reg)

function test12(){
    this.data = "some data";
    return new Error('error')}var t12 = new test12()
console.log(t12)
console.log(Object.prototype.toString.call(t12))
var err = new Error('error')
console.log(typeof err)
Copy the code

  1. When the return an Object/Function/Array/Date/RegExp/Error instance, new operator is the outcome of the return

implementation

new.target

function newOperator(ctor){
    // validates the constructor
    if(typeofctor ! = ='function') {throw ctor + 'is not a constructor';
    }
    / / set the new target
    newOperator.target = ctor;
    // Create an instance object
    var rtn_obj = Object.create(ctor.prototype);
    // Get other parameters
    var params = Array.prototype.slice.call(arguments.1);
    // Pass in the argument, bind this, and get the result returned by the constructor
    var instance = ctor.apply(rtn_obj, params);
    
    // Determine the type returned by the constructor
    var isObject = typeof instance === 'object'&& instance ! = =null;
    var isFunction = typeof instance === 'function';
    if(isObject || isFunction){
        return instance;
    }
    
    return rtn_obj;
}
Copy the code

reference

Can you simulate implementing JS’s new operator