zoukankan      html  css  js  c++  java
  • 为什么要做A.prototype.constructor=A这样的修正?

    虽然看过这篇博文JavaScript prototype之后对原型理解不再那么模糊了,但是依然还有很多理解不甚透彻的地方。比如,今天看到一个原型式继承的例子,又有些困惑,于是找了些帖子看看,有了一些自己的理解,贴在这里,希望理解不对的地方大家可以帮我指出来,多谢了!

    先看一段代码:

    function Person(){
        console.log("in 'Person'");
    }
    function Woman(){
        console.log("in 'Woman'");
    }
    
    var woman=new Woman();//in 'Woman'
    woman.constructor;//function Woman(){console.log("in 'woman'");}
    
    var person=new Person();//in 'Person'
    person.constructor;//function Person(){console.log("in 'person'");}

    以上定义了两个function,各自实例化出一个对象后,在console中查看它们的constructor,一切正常。目前两个function之间还没有任何关系,下面用prototype让它们之间挂钩。设置Woman类的prototype是Person类,这个时候再来查看constructor的情况。

    function Person(){
        console.log("in 'Person'");
    }
    function Woman(){
        console.log("in 'Woman'");
    }
    Woman.prototype=new Person();
    
    var woman=new Woman();//in 'Woman'
    /**constructor指向的是Person函数**/
    woman.constructor;//function Person(){console.log("in 'person'");}
    
    var person=new Person();//in 'Person'
    person.constructor;//function Person(){console.log("in 'person'");}

    可以看到woman的constructor指向了Person函数,这是为什么呢?

    我的理解

    我们知道,每个函数都有默认的prototype,这个prototype.constructor默认指向的就是这个函数本身。在未给Woman指定Person作为原型之前,Woman.prototype.constructor或者woman._proto_.constructor指向的就是Woman函数。但是当这样做之后:

    Woman.prototype=new Person();

    Woman函数的prototype被覆盖成了一个Person对象。
    我们知道,constructor始终指向的是创建本身的构造函数,因此Woman.prototype.constructor自然就指向了创建Woman.prototype这个Person对象的函数,也就是Person函数。这样一来,woman对象的constructor指向就不对了,因此在网上大多关于原型继承的帖子里都会建议我们做这样的修改:

    Woman.prototype.constructor=Woman;
    var woman=new Woman();//in 'Woman'
    woman.constructor;//function Woman(){console.log("in 'woman'");}

    这样修正以后,constructor的指向就正确了。

    但是,为什么要这样修正呢?不修正会有什么后果呢?

    为何要做A.prototype.constructor=A这样的修正?

    这是我最困惑的地方,因为我试验后发现,就算不做这样的修正,new Woman()的时候也不会有什么问题,虽然我还不理解JS是如何做到的,但是它确实找到了正确的构造函数去做实例化。最后我在stackoverflow上找到了一个回答What it the significance of the Javascript constructor property?,里面提到:

    The constructor property makes absolutely no practical difference to anything internally. It's only any use if your code explicitly uses it. For example, you may decide you need each of your objects to have a reference to the actual constructor function that created it; if so, you'll need to set the constructor property explicitly when you set up inheritance by assigning an object to a constructor function's prototype property, as in your example.

    所以,即使不做这样的修正也不会有什么影响,它主要防止一种情况下出错,就是你显式地去使用构造函数。比如,我并不知道woman是由哪个函数实例化出来的,但是我想clone一个,这时就可以这样:

    var woman = new Woman();
    ...
    ...
    ...
    var woman1 = woman.constructor();
  • 相关阅读:
    Delphi Variant 通用类型[3] 流 Stream的相互转换
    Delphi System单元 Utf8ToAnsi、AnsiToUtf8、Utf8Decode、Utf8Encode、Utf8ToUnicode、UnicodeToUtf8 转换
    OCR (Optical Character Recognition,光学字符识别)
    使用Python写Windows Service服务程序
    双精度张量内核加快了高性能计算
    A100计算能力
    A100 Tensor核心可加速HPC
    A100 GPU硬件架构
    NVIDIA深度架构
    稀疏性如何为AI推理增加难度
  • 原文地址:https://www.cnblogs.com/answercard/p/5297349.html
Copyright © 2011-2022 走看看