【问题标题】:Explaination for this object.prototype syntax此 object.prototype 语法的说明
【发布时间】:2016-12-10 05:15:58
【问题描述】:

我想知道为什么当我console.log(Triangle.prototype) 时,它只显示 {} 而不是显示实际的构造函数及其属性side1 side2 等当我console.log(Triangle.prototype.constructor) 时它会显示函数构造函数。还有Triangle.prototype.constructor = Triangle 做什么?为什么我再次将 Triangle 构造函数设置为 Triangle 构造函数。当我这样做时,Triangle.prototype = new Shape(),我通过继承Shape() 属性来进行继承,对吗?并且执行Triangle.prototype.constructor = new Shape() 实际上会覆盖原来的 Triangle 构造函数本身?

var Shape = function(){
    this.type = '';
}

Shape.prototype.get_type = function(){
    return this.constructor;
}

var Triangle = function(s1, s2, s3){
    this.s1 = s1;
    this.s2 = s2;
    this.s3 = s3;
}


Triangle.prototype = new Shape();

Triangle.prototype.constructor = Triangle;

module.exports = Triangle;

【问题讨论】:

标签: javascript


【解决方案1】:

在您的示例代码中,他们明确设置了构造函数,因为这是酷孩子所做的。这允许人们确定一个人可能正在使用哪种“类型”的实体。

var kid = new Bob();
console.log( kid == instanceof Bob ); // -> true

因此,通过显式设置构造函数,您可以将其更改为其他内容。但除了将“构造函数”属性指向另一个函数之外,它不会影响其他任何东西。

更多信息

构造函数不是很有用,但它已被写入语言。在较新版本的 Javascript(例如 ES6-7)中,他们开始使用它做更多事情。

当您在代码中看到“构造函数”时,不要担心它。 “构造函数”只是一个指向主函数的无意义属性。

更改“构造函数”属性不会改变原型或影响任何东西。

函数本身就是一个构造函数。所以也许这就是 Javascript 语言的作者包含该属性的原因,以便编译器/JavaScript 引擎可以确定哪个函数是构造函数。

令人困惑?是的。

这个例子表明“构造函数”属性就像任何其他指向函数的变量一样。

var Bob = function(){
    // This function is known as a "constructor".
}

var sameAsConstructor = Bob;

var areTheySame = Bob.prototype.constructor == sameAsConstructor;
console.log ( areTheySame ); // areTheySame = "true"

证明

这是一个示例,证明除了“构造函数”属性之外没有任何变化。

// ---------------------------------------
// A "base class"
// ---------------------------------------
var Shape = function(arg){
    this.name = arg; 
}
Shape.prototype.seeSize = function(){
    console.log("Shape.prototype.seeSize", this.size);
}
Shape.prototype.seeName = function(){
    console.log("Shape.prototype.seeName", this.name);
}

// ---------------------------------------
// Let's set up another one and try to extend 
// our "base class" using the "constructor"
// ---------------------------------------
var Circle = function(arg){
    this.size = arg; 
}

// Now let's try setting the constructor
// ... in an effort to "try" and leverage
// the Shape function.

Circle.prototype.constructor = Shape;

您可能认为 Circle 函数现在将被 Shape 函数取代?

没有。

作为测试,我们将创建一个新 Circle 的实例,然后查看我们的参数究竟“设置”了什么:

var sally = new Circle("bob");

尝试访问这些方法?

try {
    sally.seeSize();
} catch(e) {
    console.log("tried seeSize", e);
}

try {
    sally.seeName();
} catch(e) {
    console.log("tried seeName", e);
}

没有。

上面的两个“尝试”都失败了。

再次...

原型与“构造函数”属性无关。原型是完全不同的动物。

现在让我们看看我们的参数实际上已经“设置”了。在这里,我们可以看到“大小”已设置,就像 Shape 函数中的设置一样。

console.log("sally.size", sally.size); // size = "bob"

在这里,如果我们假设通过替换构造函数将设置“名称”......不。

console.log("sally.name", sally.name); // name = undefined

但是,您会看到构造函数实际上是 指向 Shape 函数...而不是 Circle 函数。

console.log("sally.constructor", sally.constructor);

所以,是的,非常混乱和毫无目的。

最后

在您的示例代码中:

Triangle.prototype = new Shape();

这会导致 Triangle 获取在 Shape 原型上定义的所有函数和属性并将它们应用到 Triangle。这样一来,任何 Triangle 实例也可以使用 Shape 中的任何方法。

然后他们“重置”构造函数以指向 Triangle,因为在设置 Triangle 的原型时,它还获取了 Shape 的“构造函数”属性。

因此,通过重置“构造函数”,他们只是确保“构造函数”属性指向正确的函数。

【讨论】:

  • instanceof 不受constructor 属性的任何影响。 constructor 只是 JS 作者的辅助属性,它不被 JS 本身内部使用。
猜你喜欢
  • 2018-01-02
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 2018-04-23
  • 1970-01-01
  • 2011-06-22
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多