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


    new 是如何创建对象实例的?
    1,new操作符做了哪些事情

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

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

    class Person {
        constructor(name) {
        	this.name = name
        }
    }
    // 创建自定义对象的实例
    const person = new Person('张三')
    // 创建具有构造函数的内置对象的实例
    const date = new Date()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

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

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

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

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

    • 3,调用构造函数Person,并将this绑定到新创建的对象obj
    Person.apply(obj)
    
    • 1
    • 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()  // 你好张三
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

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

    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}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    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: '张三'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    看完了,有所收获吗?

  • 相关阅读:
    初识计算机网络
    JavaAgent寄生在目标进程中引起的ClassNotFoundException
    IPv6 中 MAC 33:33 的由来
    Java Timer使用介绍
    关于数据通信知识的补充——第二篇
    这些软件可以快速实现图片翻译文字
    java计算机毕业设计销售管理系统源码+数据库+系统+lw文档+mybatis+运行部署
    go-fastdfs分布式文件存储集群搭建和测试
    docker 容器环境配置 mydumper
    Java-访问修饰符
  • 原文地址:https://blog.csdn.net/m0_37489258/article/details/126527088