new`是如何创建对象实例的?

new 是如何创建对象实例的?

1,new操作符做了哪些事情

new操作符的作用:创建对象的实例

用于创建一个用户自定义的对象的实例或者具有构造函数的内置对象的实例

class Person {
    constructor(name) {
    	this.name = name
    }
}
// 创建自定义对象的实例
const person = new Person('张三')
// 创建具有构造函数的内置对象的实例
const date = new Date()

new`是如何创建对象实例的?_第1张图片

比较直观的,我们new一个构造函数的时候,得到的实例继承了构造函数的属性以及原型上的属性。

以这种方式调用构造函数会经历以下4步:

  • 1,创建一个新的空对象
const obj = {}
  • 2,给这个空对象添加__proto__属性,并将空对象的__proto__指向构造函数的原型
obj.__proto__ = Person.prototype

将空对象的__proto__属性赋值为构造函数的prototype属性,使得通过构造函数创建的所有对象的实例可以共享相同的原型,这意味着同一个构造函数创建的所有对象都继承于一个相同的对象,因此他们都是同一个类的对象

  • 3,调用构造函数Person,并将this绑定到新创建的对象obj
Person.apply(obj)
  • 4,对构造函数的返回值做判断,然后返回对应的值(/返回新对象)
    • 一般是返回第一步创建的空对象
    • 但是当构造函数有返回值的时候,则需要做判断再返回对应的值,是对象类型则返回该对象,是原始类型则返回第一步创建的空对象
function Person (name) {
    // 1,创建一个新对象,赋予this,这一步是隐性的
    // let obj = {}
    // 2,给 this 指向的对象赋予构造属性
    this.name = name;
    this.sayHi = function () {
    	console.log('你好' + this.name)
    }
    // 3,如果没有手动返回对象,则默认隐性的返回this指向的对象
    // return this
}
let p1 = new Person('张三')
p1.sayHi()  // 你好张三
2,new的实现及验证说明
function myNew(constructor, ...args) {
    // 1,创建一个新对象
    let obj = {}
    // 2,将这个新对象的__proto__指向构造函数的原型 obj.__proto__ = constructor.prototype
    Object.setPrototypeOf(obj, constructor.prototype);
    // 3,将this指向空对象
    let res =  constructor.apply(obj, args);
    // 4,对构造函数的返回值做判断,并返回对应的值
    return res instanceof Object ? res : obj
}
function Person(name) {
	this.name = name;
}
let p1 = myNew(Person, '张三')
p1 // {name: '张三'}
p1.constructor === Person // true
p1.__proto__ === Person.prototype // true

一般情况下构造函数并没有返回值,作为函数的情况下,可以有返回值:

function myNew(constructor, ...args) {
    let obj = {}
    Object.setPrototypeOf(obj, constructor.prototype);
    let res =  constructor.apply(obj, args);
    return res instanceof Object ? res : obj
}
function Person(name) {
    this.name = name;
    return {   // 当构造函数返回对象类型的数据的时候,会直接返回这个数据,new操作符无效
    	age: 18
    }
}
let p1 = myNew(Person, '张三')
p1  // {age: 18}
function myNew(constructor, ...args) {
    let obj = {}
    Object.setPrototypeOf(obj, constructor.prototype);
    let res =  constructor.apply(obj, args);
    return res instanceof Object ? res : obj
}
function Person(name) {
    this.name = name;
    return '你好张三'   // 构造函数返回基础数据类型的时候,则会被忽略
}
let p1 = myNew(Person, '张三')
p1 // {name: '张三'}

看完了,有所收获吗?

你可能感兴趣的:(javaScript,javascript,原型模式,开发语言)