javascript中new关键字到底做了啥?

javascript中new关键字到底做了啥?

先看看MDN中对new的描述

MDN中对new的描述

我们可以看到,在mdn文档对new的描述中,new主要做了4个操作,大多初学者也许还不能够理解,那我们来用代码还原一下new的4个操作。

封装myNew

//封装一个myNew,来简单实现new关键字的功能

//这里的callback就是构造函数
function myNew(callback, p1, p2) {
    
    
             //对应第一个操作:创建一个空的简单JavaScript对象
            const obj = {
    
    } 
            //第二步:链接该对象
            obj.__proto__ = callback.prototype
            //第三步:将步骤1新创建的对象作为this的上下文
            callback.call(obj, p1, p2)
            //第四步:返回该对象
            return obj
        }

好啦,简简单单的几行代码,就能简单还原一下new的操作,下面我们看一下是不是一样呢。

		//定义一个简单的构造函数
		function People(name, age) {
    
    
            this.name = name
            this.age = age
        };
        //给构造函数的原型对象上添加一个实例方法
		People.prototype.say = function () {
    
    
            console.log('hello ' + this.name);
        }
        //来new一下
        //毕竟封装的myNew,使用形式上和new还是有一些区别
        const lqs = myNew(People, 'lqsss', 18)
        //直接new关键字
        const zty = new People('ztyyy', 18)
        //打印两者,顺带调用一下方法
        console.log(lqs);
        console.log(zty);
        lqs.say()
        zty.say()

结果如下:
结果
我们发现两者肉眼可见的一样!并且连__proto__.constructor也指向正确!

上面就是对new 的简单封装,但是new关键字还有许多坑!

new关键值的返回值问题

我们都知道,new的函数中,是自动返回一个实例的,但是如果手动返回一个值呢?看下述代码

 function People(name, age) {
    
    
            this.name = name
            this.age = age
            //我们在构造函数中手动返回一个对象
            return {
    
    
                name: 'zty',
                age: 18
            }
        }
        const lqs = new People('lqsss', 18)
        //我们打印new的实例
        console.log(lqs);//{name: "zty", age: 18}

我们发现在手动返回一个对象时,new的返回竟然被替换掉了!那总是会这样吗,这次我们来返回一个函数

function People(name, age) {
    
    
            this.name = name
            this.age = age
            return function () {
    
    }
        }
        const lqs = new People('lqsss', 18)
        console.log(lqs);//ƒ () {}

在收到返回函数时,构造函数的自动返回值依然被替换掉了,那么我们在试试其他数据类型

 function People(name, age) {
    
    
            this.name = name
            this.age = age
            return 'zty'
        }
        const lqs = new People('lqsss', 18)
        console.log(lqs);//People {name: "lqsss", age: 18}

这次我们手动返回了一个字符串,但是并没有替换掉自动返回的对象,构造函数还是顺利执行了!

在多次实验之后,得出一个结论!

!!!new之后的函数,如果没有手动return 则会返回一个构造函数的实例,如果手动写了return 并且return的是一个引用数据类型,那么实例会被引用数据类型替换掉!如果return的是一个简单数据类型,那么构造函数还是能顺利进行return!

猜你喜欢

转载自blog.csdn.net/lqsssssss/article/details/109344078