JavaScript obj.constructor vs obj.[Prototype]';s构造函数

JavaScript obj.constructor vs obj.[Prototype]';s构造函数,javascript,Javascript,Object.getPrototypeOf(z).constructor==z.constructor JavaScript中的每个对象z都是这样吗 我的意思是z.constructor只是一个快捷方式,让我们可以更轻松地检索 对象的内部[[Prototype]]属性的构造函数属性 或者。。。是否存在两种不同的情况,以及z.constructor值 与对象.getPrototypeOf(z).constructor值不同 我认为这只是一条捷径,但我不确定,因为我找不到 这在任何权威的文件来源中都

Object.getPrototypeOf(z).constructor==z.constructor

JavaScript中的每个对象
z
都是这样吗

我的意思是
z.constructor
只是一个快捷方式,让我们可以更轻松地检索
对象的内部
[[Prototype]]
属性的构造函数属性

或者。。。是否存在两种不同的情况,以及
z.constructor

对象.getPrototypeOf(z).constructor
值不同

我认为这只是一条捷径,但我不确定,因为我找不到
这在任何权威的文件来源中都有明确说明

编辑: 下面的代码显示,设置
Object.getPrototypeOf(z).constructor
也会隐式设置其他值。但是设置
z.constructor
不会设置其他值。
所以现在我很困惑。。。这是如何实现的?似乎
z。构造函数
不仅仅是一种快捷方式,而是某种复制品。但是,如果它是一个副本,当我们将
对象.getPrototypeOf(z).constructor
更改/设置为一个新值时,它为什么会受到影响

    function Animal() {

        this.ttype = "Animal"

    }

    function Plant(){
        this.ttype = "Plant"
    }

    var p1 = new Plant();
    console.log(p1.constructor);
    console.log(p1.constructor === Object.getPrototypeOf(p1).constructor);
    p1.constructor = Animal;
    console.log(p1.constructor === Object.getPrototypeOf(p1).constructor);

    var p2 = new Plant();
    console.log(p2.constructor);
    console.log(p2.constructor === Object.getPrototypeOf(p2).constructor);
    Object.getPrototypeOf(p2).constructor = Animal;
    console.log(p2.constructor === Object.getPrototypeOf(p2).constructor);
    console.log(p2.constructor);

对象的
构造函数
属性通常从其原型链继承。有两个例外:

  • 其原型链不包含任何对象的对象。它们可以使用
    Object.create(null)
    创建,并且对于设置不受从其他地方继承的属性影响的查找表非常有用

  • 已分配了名为
    构造函数的本地“自有”属性的对象,如

    myObject.constructor = 42;
    
    然而,这是一个技术性问题,而不是您期望在实际代码中看到的东西

  • 所以撇开这些不谈,
    constructor
    从何而来

    通过语言设计,
    构造函数
    继承自构造函数的
    原型
    属性。JavaScript中的每个普通函数都设置了
    prototype
    属性,并将名为
    constructor
    的不可枚举属性设置为函数对象本身。通过这种方式,任何标准函数都可以作为构造函数调用,无需修改。然而,开销是,无论如何,从未打算用作构造函数的标准函数都有
    prototype
    属性

    现在更复杂的是:

  • 标准函数对象的
    prototype
    属性是可写的。如果更新为新的对象值,则函数构造的对象将继承ammended
    prototype
    对象的
    constructor
    ,这通常不同于被覆盖的
    prototype
    值的
    constructor


  • 函数的
    原型
    属性的
    构造函数
    属性没有写保护

    • 结合这两个因素,可以建立任意长度的原型链,部分模拟基于类的语言中类的扩展。例如,如果
      C
      对象继承自
      B
      ,而该对象继承自
      A
      ,则您可以编写

      B.prototype = new A()  // B objects inherit from an instance of A,
                             // which inherits from A.prototype
      C.prototype = new B()  // C objects inherit from an instance of B,
                             // which inherits from B.prototype and A.prototype
      C.prototype.constructor = C;     // C objects inherit C as their constructor.
      
  • 这些链接原型的经典规则非常松散:您可以多次更改
    prototype
    属性,而不会影响以前创建的对象的继承链。然而,多次更改构造函数的
    prototype
    属性的用途有限(为
    对象创建polyfill.create
    可能),而且最不寻常

    请注意,创建构造函数的
    class
    关键字语法会使这种操作过时-您不能更改类构造函数
    prototype
    属性,如果您扩展了“类”扩展类的
    prototype
    属性继承自基类的
    prototype
    属性,同时将其
    constructor
    属性自动设置为扩展构造函数

    还要注意的是,箭头函数没有
    prototype
    属性,不能用作构造函数


    q1

    Object.getPrototypeOf(z).constructor===z.constructor

    JavaScript中的每个对象z都是这样吗

    是,除1)和2)中列出的例外情况外

    问题2

    p1.constructor=动物

    这将创建一个自己的
    p1
    属性,该属性会隐藏继承的
    构造函数
    属性,该属性无法再访问(异常2)

    第三季度

    Object.getPrototypeOf(p2).constructor=Animal


    这行代码更新对象的
    constructor
    属性,其中
    p2
    从中继承其
    constructor
    值,因此
    p2
    的继承构造函数属性现在是
    Animal
    。类似地继承自
    plant.prototype
    的其他plant对象也会将
    Animal
    视为其构造函数。

    您的对象可以具有
    构造函数
    属性,如:
    z.constructor=()=>“custom”
    。另外,如果您有
    z=Object.create(null)
    ,则
    Object.getPrototypeOf(z).constructor
    将抛出一个errorHm。。。所以这不仅仅是一条捷径。但是,如果我设置
    Object.getPrototypeOf(z).constructor,则两者保持不变。这是如何实现的@adiga当我们通过
    对象创建对象时,我们先不考虑这种情况。create(null)
    假设它有非null的
    [[Prototype]]
    ,除非对象有自己的
    构造函数
    属性,否则条件是true@adiga哦等待所以你是说这仅仅是一个标准的查找过程,它发生在我们试图访问任何对象
    z
    (即
    z.constructor
    pro)的任何属性上