当你用new创建新对象的时候发生了什么?隐式对象 | 原型链 | 隐式绑定

122 阅读3分钟

当你用new关键字创建对象的时候发生了什么,比如

const obj = new ClassOrConstructorFunction()

1.创建空对象:js会创建一个新的空对象,这个空对象将会是一个类或是构造函数的一个实例

类(Class)和构造函数(Constructor Function)有什么区别? 记住js中的类只是构造函数和基于原型的继承的语法糖,类本质上还是一个函数,typeof SomeClass //Function

2.构建原型链(隐式):将新创建对象的[[Prototype]]指向构造函数的prototype属性,这是因为对象需要继承其父对象的属性和方法,而我们知道js是通过原型(prototype)来实现继承的

这里简单说一下原型和继承

以下是你需要知道的

2.1.__proto__ prototype 是什么?

__proto__ 每一个对象都有的一个属性(空对象{},它的__proto__ 指向Object,所有对象都能访问Object的对象的属性和方法,因为它是所有对象的父类),它指向创建其构造函数的prototype属性,以此来继承构造函数原型里的属性和方法

prototype构造函数或类拥有的一个属性,它包含了其所有实例该继承的属性和方法。 由此你可以理解为,其实它们是同样的东西,只是访问的方式不同,通过对象访问__proto__,而通过类和构造函数访问prototype

2.2.__proto__ [[Prototype]]的区别是什么

两者都指向构造函数的prototype属性,__proto__ 可以直接访问,如obj.__proto__;[[Prototype]]是内部的属性,代码无法访问,用于原型链内部的机制

__proto__不是标准的属性,已经弃用,推荐用Object.getPrototypeOf(),详情见这里

3.隐式绑定'this'和执行构造函数体:以新对象为上下文(即this指向新对象)构造函数被调用,如果是构造函数则调用其本身,如果是类,则调用里面的constructor构造函数。使用 this 分配的任何属性或方法都会添加到新对象中。

4.返回新创建的对象(隐式),构造函数自动返回新创建的对象,当然你在构造函数里没有用return显式返回一个对象(通常我们不这么做)

大概就是这么个过程,下面看代码,代码会有注释,配合文字,希望你能理解

    //这里用构造函数作为演示
    function Car(make, model) {
        // 这只是一个mental model,你可以概念性的想象成这样
        // 1.隐式创建一个新对象,并将this指向它
        // let this = {} 
        
        // 2.隐式构建原型链
        // Object.setPrototypeOf(this,Car.prototype)
        
        // 3.执行构造函数体,其实就是赋值和各种预置逻辑(set-up logic)
        this.make = make;
        this.model = model;
        
        // other set-up logic
        
        // 4.隐式返回新创建的对象
        // return {make,model} 相当于{make:make,model:model}
    }

来尝试实现一个new关键字的功能吧,思路和步骤都写在代码里