谈谈JS new运算符到底做了些什么

一、关于new

在面向对象的语言中,new关键字总是用于实例化一个对象
在JavaScript中,作为一个运算符,new常与构造函数一起使用

let map = new Set() 
function Apple(size,color){
    
    
    this.size = size
    this.color = color
} 
let apple = new Apple('huge','red') 

二、new与构造函数

既然new与构造函数紧密联系,不妨从构造函数的角度来探讨一下new究竟做了什么

2.1 构造函数的this指向

new的作用之一:创建实例的构造函数绑定与构造函数的this绑定
众所周知,对于一个普通函数,它的this一般指向函数的调用者
但是当它与new作用,它的this便会指向被创造出来的实例

function Apple(size,color){
    
    
    console.log(this)
    this.size = size
    this.color = color
} 
Apple('huge', 'red') // window
let apple = new Apple('huge', 'red')  // Apple {}
console.log(apple.constructor) // [Function: Apple]

2.2 构造函数的返回值

new的作用之二:为构造函数指定一个默认非undefined的返回值
函数都拥有返回值,当一个函数没有return时,它默认返回undefined
实例可以看作是构造函数的返回值
在实例化过程中,如果为构造函数指定了引用类型的返回值,那么返回该引用类型;如果构造函数没有返回值,或者说指定了基本类型的返回值,那么它返回this(新创建的实例)

function Apple(size,color){
    
    
    this.size = size
    this.color = color
    // case 1
    return {
    
    
        self:true
    }
    // case 2
    return 'self'
    // case 3 
    return 
} 
console.log(new Apple('huge', 'red')) // case1 {self:true}  case2、3  Apple {}

2.3 构造函数与实例的继承关系

new的作用之三:将实例的原型链指向构造函数的原型
实例由构造函数创建,实例的原型链指向构造函数的原型,因此实例拥有构造函数原型上的属性
一般来说,一个实例的原型链是这样的:apple.proto --> Apple.Prototype --> Object.Prototype --> null

function Apple(size) {
    
    
    this.size = size
}
Apple.prototype.height = '100mm'
Apple.width = '80mm'

let apple = new Apple('huge')

console.log(
    apple.size,  // huge 
    apple.height, // 100mm
    apple.width  // undefined
)

Apple.prototype.width = '70mm'

console.log(apple.width) // 70mm
console.log(Object.getPrototypeOf(apple) === Apple.prototype) // true

三、总结: new运算符究竟做了什么

经过上面的叙述之后,对于“new运算符究竟做了什么”已经有了答案

JavaScript在通过new创建实例的过程中,一共做了以下事情:

  1. 创建一个空对象 instance
  2. 绑定构造函数的this,使其指向instance,执行构造函数为instance设置属性
  3. 将instance的原型链指向构造函数的原型
  4. 如果构造函数指定了引用类型的返回值ret,那么返回ret,否则返回instance

四、后续: 如何实现new运算符

查看另一篇博客 实现JS new运算符

猜你喜欢

转载自blog.csdn.net/qq_41109610/article/details/113478533