Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 更改构造函数的问题';s原型_Javascript - Fatal编程技术网

Javascript 更改构造函数的问题';s原型

Javascript 更改构造函数的问题';s原型,javascript,Javascript,我正在阅读斯托扬·斯特凡诺夫的书《面向对象的JavaScript》,我偶然发现了一个有趣的问题。代码如下: var shape = { type: 'shape', getType: function() { return this.type; } }; function Triangle(a, b, c) { this.a = a; this.b = b; this.c = c; this.type = 'triangl

我正在阅读斯托扬·斯特凡诺夫的书《面向对象的JavaScript》,我偶然发现了一个有趣的问题。代码如下:

var shape = {
    type: 'shape',
    getType: function() {
        return this.type;
    }
};

function Triangle(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
    this.type = 'triangle';
}

Triangle.prototype = shape; // changing the prototype object
Triangle.prototype.getPerimeter = function() {
    return this.a + this.b + this.c;
}

var t = new Triangle(1, 2, 3);
t.constructor; // logs Object() instead of Triangle(a, b, c)
如您所见,这里是一个简单的构造函数示例,它从prototype对象中继承了一些属性。但是对象t的构造函数属性指向object()对象,而不是它应该指向的三角形(a,b,c)。不过,如果我用原型更改来评论这一行,一切都很好。我有什么问题? (重读面向对象Javascript和Javascript模式的整个原型章节,找不到答案)。 另外,很抱歉我的英语不好,正在努力练习。:)

奇怪的是,“constructor”属性没有引用该对象的构造函数。相反,它指的是对象原型的构造函数


是Mozilla的相关文档页。

形状是一个对象,因此通过执行此操作:

Triangle.prototype = shape;

三角形
构造函数更改为
对象

形状不是构造函数,而是对象。它的构造函数是对象构造函数

如果shape是一个构造函数,那么您可以设置

三角形。原型=新形状


和Triangle.prototype.constructor=Triangle,以覆盖您刚才设置的shape.prototype.constructor。

我将分两部分解释您的代码。首先,
构造函数
属性实际上是什么?其次,为什么它不在代码中返回
对象

构造函数
属性和斯托扬的错误: 在斯托扬·斯特凡诺夫的书p150中,他指出:

prototype是定义函数后立即创建的属性其初始值为空对象。

这是错误的。根据第9.2节

原型属性的初始值是具有单个属性的对象此属性名为constructor,并返回与原型关联的构造函数

您可以使用
Triangle.prototype.constructor
对其进行测试。它是在定义函数时设置的

结论1
构造函数
实际上是
构造函数的属性。原型
。在您的例子中,它是
Triangle.prototype.constructor

Triangle
的所有实例都可以通过原型链访问此属性但是这些对象本身没有
构造函数
属性
。下面的代码证明了这一点:

function Triangle(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
    this.type = 'triangle';
}
var t = new Triangle(1, 2, 3);
t.hasOwnProperty('constructor');
>>false
t.__proto__.hasOwnProperty('constructor');
>>true
结论2:当您访问实例的
构造函数
属性时,您可以从原型链获取它们

为什么它没有像你期望的那样工作 您将
Triangle.prototype
设置为
shape
,该不包含原始
构造函数
属性

因此,这一次,当您查询
t.constructor
时,它将在以下过程中解析它:

  • 查看它自己的属性,发现没有
    constructor
  • 继续查找
    t.\uuuuu proto\uuuu
    ,即
    Triangle.prototype
    。您已将其设置为
    shape
    ,它不包含
    构造函数
    属性
  • 继续沿着原型链向上查找-
    t.\uuuuu proto\uuuu.\uuuuuu proto\uuuu
    。它是
    Triangle.prototype.\uuuu proto\uuuu
    ,它被解析为
    Object.prototype
    <代码>对象。原型
  • 具有
    构造函数
    属性,它引用
    对象

    在这里的示例中,基本上使用的是本机/基于类的继承。 在Javascript中,(据我所知),当您使用
    new
    关键字时,您将创建一个带有构造函数和附加原型对象的函数对象

    执行此操作时:

    Triangle.prototype = shape;
    
    您重写构造函数方法。您可以使用控制台在将形状指定给
    Triangle.prototype
    之前和之后观察对象

    然后执行此操作时:

    t.constructor;
    
    当调用构造函数方法在原型链中找到构造函数方法时,您无法查看您希望看到的内容

    var形状={
    键入:“形状”,
    getType:函数(){
    返回此.type
    }
    }
    函数三角形(a,b,c){
    this.type='triangle'
    这个a=a;
    这个.b=b;
    这个.c=c;
    }
    三角形。原型=形状;
    Triangle.prototype.constructor=三角形;
    Triangle.prototype.GetPermission=函数(){
    归还这个。a+这个。b+这个。c
    }
    var t=新三角形(1,2,3)
    console.log(t.constructor==Triangle)//true
    console.log(shape.isPrototypeOf(t))//true
    console.log(t.getPermission())//6
    
    console.log(t.getType())//triangle
    当然,我怎么会忘记读过它呢。应该多练习而不是阅读。:)proto是隐藏属性,未在js规范中定义,不受支持。使用它是不安全的。请不要只发布代码作为答案,还要解释代码的作用以及如何解决问题。带有解释的答案通常更有帮助,质量更好,更容易吸引选票。