Javascript:默认原型字段显示使用null构造函数创建的对象的未定义

时间:2016-09-30 15:40:11

标签: javascript oop object constructor prototype

我注意到下面代码中的某些行为,我无法解释。我希望有人可以告诉我为什么会这样。

下面的代码示例也可以在JSFiddle上获得,如果它更容易阅读。 {{3}}

代码:

function Book() {

};

function Book (title, author) {
    this.title = title;
  this.author = author;
};

Book.prototype = {
    title: "",
  ISBN: "isbn",
  length: 100,
  genre: "genre",
  covering: "covering",
  author: "author",
  currentPage: 0,

  toString: function toString() {
    console.log("toString Function");
    console.log('Title: ' + this.title + '\n' +
                            'ISBN: ' + this.ISBN + '\n' + 
                            'length: ' + this.length + '\n' + 
                'genre: ' + this.genre + '\n' + 
                'covering: ' + this.covering + '\n' + 
                'author: ' + this.author + '\n' + 
                'currentPage: ' + this.currentPage + '\n');
  }
};

var book1 = new Book();
book1.toString();

var book2 = new Book("First edition", "Random");
book2.toString();

book1.toString()的输出 toString函数 标题:未定义 ISBN:isbn 长度:100 类型:流派 覆盖:覆盖 作者:undefined currentPage:0

book2.toString()的输出 toString函数 标题:第一版 ISBN:isbn 长度:100 类型:流派 覆盖:覆盖 作者:随机 currentPage:0

我的困惑围绕着作者和标题领域。在null构造函数中,这些字段默认为" undefined"而不是Book类原型中列出的那些。

感谢任何帮助过此事的人。

干杯,Cam。

3 个答案:

答案 0 :(得分:1)

JavaScriptJava(或其他编程语言)不同,如果它们具有不同数量或类型的参数,则可以使用具有相同名称的方法或多个构造函数。在这种情况下,您已将Book()替换为Book(title, author)

要达到你想要的效果,你可以这样做:

function Book (title, author) {
    this.title = title||"";
    this.author = author||"";
};

在这种情况下,titleauthor默认为空String

或类似的东西:

function Book (title, author) {
    this.title = title && author ? title : "";
    this.author = title && author ? author : "";
};

答案 1 :(得分:1)

您在函数构造函数中定义的属性将始终覆盖原型上定义的属性。

当JavaScript引擎提供原型值时,它将首先在实例上查找它(hasOwnProperty),而不是它的原型链。

因为你在函数构造函数中隐式声明了title和author,所以 new 操作符在它的实例空间上创建了具有这两个属性的对象,所以对象看起来像这样:

图书{    标题:未定义,    汽车:未定义,    的:{        标题:“”,        ISBN:“isbn”,        长度:100,        类型:“流派”,        覆盖:“覆盖”,        作者:“作者”,        currentPage:0,         proto :对象    } }

因此,当首次要求该属性时,JavaScript引擎将返回已初始化为undefined的实例上的那些,因为在使用 new 创建时没有传递参数。

答案 2 :(得分:1)

在您最初的图书功能

function Book (title, author) {
  this.title = title;
  this.author = author;
};

你没有传递任何东西,所以参数进入函数的未定义。由于您同时声明了标题作者,因此您仍在为它们分配值,在本例中为未定义

Book 对象的第一次查找会命中您声明的属性,这两个属性都有一个值,因此您将获得 undefined 的返回值。由于 Book 的这两个属性都有值,因此查找会停止,并且不会像您最期望的那样传播到原型链中。

如果您希望在将参数传递给被调用函数时设置默认值,则只需将其添加到您的函数中。

function Book (title, author) {
  this.title = title || "";
  this.author = author || "author";
}