一天一个知识点 - 浅谈 JavaScript new 究竟做了什么?

354 阅读2分钟

前言

前些日子,在掘金上看到一片热门文章《在酷家乐做面试官的日子》。该文作者以面试官的角度,详细阐述了作为一名 web 应聘者应该具有哪些技能,才会更让人青睐。

在对比自身的过程中,发现有一些问题,或许了解,但不全面,这也是本系列文章诞生的缘由。

new 的定义

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

一个简单例子


function obj(msg){
    this.msg = msg
    
    this.talk = function(){
        console.log(this.msg)
    }
}

obj.prototype.p = '我是构造函数 obj 的原型对象的一个属性'

var o = new obj('hello world')

使用 new 操作符实例化一个对象,会发生以下事情:

  1. 一个继承自 obj.prototype 的新对象被创建。
  2. 使用指定的参数调用构造函数 obj ,并将 this 绑定到新创建的对象。
  3. 由构造函数返回的对象就是 new 表达式的结果。

// 验证1 : 一个继承自 obj.prototype 的新对象被创建 
// o.[[Prototype]] 指向 obj.prototype(或者说 bbj.[[Prototype]])
o.__proto__ === obj.prototype => true
// o.[[Prototype]].[[Prototype]] 指向 Object
o.__proto__.__proto__ === Object.prototype => true

// 验证2 : 一个继承自 obj.prototype 的新对象被创建 
// o 拥有自身属性 msg 和 talk 函数
o => obj {msg: "hello world", talk: ƒ}
// o 是 obj 的一个示例
o instanceof obj => true

// 验证3 : 由构造函数返回的对象就是 new 表达式的结果
// o 是一个实例对象, 是 new 表达式的结果
o => obj {msg: "hello world", talk: ƒ}

使用伪代码解释 new 的过程


// step 1. 创建一个新对象 o
var o = {}

// step 2. o.原型对象 指向 F 的原型对象
o.__proto__ = F.prototype

// step 3. 将 this 绑定到 o
F.call(o)

// step 4. 返回新对象 o
return o

参考

系列文章