new的实现

本文探讨了JavaScript中构造函数与原型的关系,解释了为什么原型覆写通常在构造函数外部进行,以及`new`操作符的工作原理。通过模拟`new`实现,展示了在构造函数内覆写原型可能导致的第一个实例无法继承的情况,而后续实例则可以。重点在于理解原型链的建立时机与构造函数执行的顺序对继承的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,关于原型覆写为什么要在构造函数外

    	function Parent(){
            this.name ='parent'
            this.play=[1,2,3]
        }
        function Child(){
            this.type='child'
            Child.prototype=new Parent();  //undefined
        }
       //  Child.prototype=new Parent();  * //parent
            let son = new Child();
            console.log(son.name)

二,new实现的过程
1.创建一个空的简单Javascript对象 (即{});

2.链接该对象(即设置该对象的构造函数)到另一个对象;

3.将步骤1新创建的对象作为this的上下文;

4.如果该函数没有返回对象,则返回this;

三. 模拟一个new

function myNew(fn) {
    let o = Object.create(fn.prototype)
    let k = fn.call(o);
    if (typeof k === 'object') {
        return k;
    } else {
        return o;
    }
        
}

四.关于原型写在构造函数里,输出undefined问题
在new一个实例的时候,先是将这个空对象附加一个__proto__属性指向原型对象,也就是说先连接原型对象再执行构造函数中的代码。

      function Parent(){
            this.name ='parent'
            this.play=[1,2,3]
        }
        function Child(){
            this.type='child'
            Child.prototype=new Parent(); 
        }
         let son1 =new Child();
         console.log(son1.name) //undefined

在new 一个son1的时候,连接原型,执行构造函数

function myNew(fn) {
    // 以构造函数fn的prototype为原型 创建一个新的简单对象
    let o = Object.create(fn.prototype)
    // 改变fn的this指向到o,并执行fn
    let k = fn.call(o);
 
    // 如果构造函数没有返回对象,则返回o
    if (typeof k === 'object') {
        return k;
    } else {
        return o;
    }
        
}

这里要注意了:如果构造函数没有返回对象,则返回o !
明显我们new son1的时候,k不是对象,它只是执行了Child的构造函数,最终我们的son1接收的是o的值。
那么我们在执行构造函数时,遇见了这条语句
Child.prototype=new Parent();
执行了吗?执行了,但是这条语句无法影响到o,因为o的原型已经赋完值了,o指向的是最初的Child原型,后面再改变构造函数Child的原型指向,但此时无法影响到o了。
再看:

		 function Parent(){
            this.name ='parent'
            this.play=[1,2,3]
        }
        function Child(){
            this.type='child'
            Child.prototype=new Parent(); 
        }
         let son1 =new Child();
         console.log(son1.name) //undefined
         let son2 =new Child();
         console.log(son2.name) //parent

son2为什么能够继承Parent?
因为在第一次new的时候改变了Child的原型指向,能够使得后续的实例能够实现继承

总之:
在构造函数中覆写原型能够使后续实例实现继承
但是第一个实例它的原型对象是开始的,后面又被改变了,可以说这份最开始的原型对象是第一个实例所独有的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值