new操作符具体干了什么

361 阅读1分钟

作用:

new操作符用于创建一个给定构造函数的实例对象

过程:

1.创建一个新的空对象{}

2.将空对象的_proto_属性指向构造函数的prototype属性,即将对象与构造函数通过原型链连接起来

3.将空对象作为构造函数的 this 上下文,执行构造函数,即改变构造函数的this为要创建的实例对象,再执行一遍构造函数

将构造函数中的this绑定到新建的对象obj上:

FN.call(obj,'jack')

4.返回新对象

5.根据构造函数返回类型做判断,如果是原始值则被忽略,如果是返回对象,需要正常处理

手写new操作符

// 手写new操作符
function FUNC(name,age){
    this.name = name 
    this.age = age 
}
function selfInstance(FUNC,...arg){
    //1.创建一个新的对象
    let obj = {}
    //2.新对象原型指向构造函数原型对象
    obj._proto_ = FUNC.prototype
    //3.将构造函数的this指向新对象
    let result = FUNC.call(obj,...arg)
    //4.根据返回值判断,这里需要判断吗?
    return result instanceof Object ? result : obj
}
let myInstance = selfInstance(FUNC,'嘿嘿嘿',20)
console.log('myInstance',myInstance);

image.png

上面代码中的:

let result = FUNC.call(obj,...arg)

给通过 new 操作符创建的实例对象时,this指向埋下了伏笔:

function FN(){
    console.log('FN中的this',this)
}
let fn = new FN()

image.png

+若构造函数中返回一个原始类型,则这个返回值没有作用

function fn1(school){
    this.school = school
    return '大学'
}
let fn1Instance = new fn1('理工')
console.log(fn1Instance.school); //'理工'

+若构造函数返回一个对象,那么这个对象将被正常使用

function fn2(school){
    this.school = school
    return {age: '大学'}
}
let fn1Instance2 = new fn2('理工')
console.log(fn1Instance2.school); //undefined

\