一、关于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创建实例的过程中,一共做了以下事情:
- 创建一个空对象 instance
- 绑定构造函数的this,使其指向instance,执行构造函数为instance设置属性
- 将instance的原型链指向构造函数的原型
- 如果构造函数指定了引用类型的返回值ret,那么返回ret,否则返回instance
四、后续: 如何实现new运算符
查看另一篇博客 实现JS new运算符