【问题标题】:JavaScript parameter value becomes undefined when passed through prototype chainJavaScript 参数值在通过原型链传递时变为未定义
【发布时间】:2017-07-21 19:24:21
【问题描述】:

我已经在 ParentChild 之间建立了原型继承,所有参数都来自 JSON 文件的 XMLHttpRequest。在将 JSON 文件传递​​给 Child 构造函数 之前,我已经通过每个参数的 typeof 语句确认 JSON 文件是正确构建的。

由于某种原因,stringArray 的类型在到达 Child.prototype.setText 时从 object 变为 undefined strong> 并在移动到继承的 Parent.prototype.joinStringArray 时抛出 TypeError

编辑:我已经包含了 JSON 数据的当前格式以及预期的 i/o;

JSON 文件输入:

{ 
  "products":[
    {"name":"Product 1","materials":["mat1","mat2"],"gloss":false},
    {"name":"Product 2","materials":["mat1"],"gloss":true},
    {"name":"Product 3","materials":["mat1","mat2","mat3"],"gloss":true},
    {"name":"Product 4","materials":["mat1"],"gloss":false}
  ]
}

HTML/JavaScript 进程:

<main id="screen">
</main>
<script>
  // XMLHttpRequest() receives data in "var catalog"
  var product = new Child(catalog.products[0].name, catalog.products[0].materials, catalog.products[0].gloss);
  // DOM Insertion
  var productName = document.createElement("H2");
  productName.innerHTML = product.name;
  document.getElementById("screen").appendChild(productName);
  var productDesc = document.createElement("P");
  productDesc.innerHTML = product.text;
  document.getElementById("screen").appendChild(productDesc);
</script>

JavaScript 对象:

/* PARENT */
function Parent(name, stringArray) {
  this.name        = name;
  this.stringArray = stringArray;
  this.text        = this.setText(stringArray);
}
Parent.prototype.setText = function(stringArray) {
  // Generate a paragraph
  return this.name + ": made from " + this.joinStringArray(stringArray) + "."; 

}    
Parent.prototype.joinStringArray = function(stringArray) {
  var stringList = stringArray[0];
  for (var i = 1; i < stringArray.length; i++) {
    stringList += (i == (stringArray.length - 1) ? " and " : ", ") + stringArray[i];
  }
  return stringList.toLowerCase();
}

/* CHILD */
function Child(name, stringArray, boolean) {
  Parent.call(this, name, stringArray);
  this.boolean = boolean;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.setText = function(stringArray) {
  // Generate a paragraph
  return this.name + ": this " + (this.boolean ? "TRUE variant" : "FALSE variant") 
                   + " is made from " + this.joinStringArray(stringArray) + ".";
}

预期输出:

<main id="screen">
  <h2>Product 1</h2>
  <p>Product 1: this FALSE variant is made from mat1 and mat2.</p>
</main>

实际输出:TypeError: stringArray is undefined

【问题讨论】:

  • 你能告诉我们你是如何使用这些类的吗?与实际结果相比,您的预期结果是什么?你能举一个简单的例子来说明你的输入吗?
  • @JoelCDoyle - 这就是你要找的东西吗? (编辑操作)
  • 太好了,现在实际输出是什么?错误是什么?据我所知,在我的 plunker 中它工作正常。
  • 我已经在 OP 的开头包含了错误,但我已经复制了下面的确切控制台错误。

标签: javascript inheritance parameters prototype undefined


【解决方案1】:

(感谢 cmets 中的 JoelCDoyle 提醒我声明顺序很重要!)

此继承设置是一个更大的对象树的一部分,该对象树在父构造函数中调用了几个其他变量。我尝试只提取负责我遇到问题的系统的代码,但似乎无意中解决了我的问题。

我的代码的相关部分如下,但添加了 vendor 参数

/* PARENT */
function Parent(vendor, name, stringArray) {
  // PROPERTIES
}
// METHODS

}    
/* CHILD */
function Child(name, stringArray, boolean) {
  Parent.call(this, name, stringArray, this.vendor);
  this.vendor = "SomeVendor";      
  this.boolean = boolean;
}

每个 子对象 都有一组 vendor 传递给 Parent(以及我没有包括的其他几个变量)。这些代码行之间有足够的距离,我没有注意到参数顺序不同。

所以,当 JoelCDoyle 提到我的 Child 属性 需要移到 Parent 调用 之上时,我将它们复制粘贴到它之上。就在那时我注意到了这个问题并纠正了它:

/* PARENT */
function Parent(vendor, name, stringArray) {
  // PROPERTIES
}
// METHODS

}    
/* CHILD */
function Child(name, stringArray, boolean) {
  this.vendor = "SomeVendor";      
  this.boolean = boolean;
  Parent.call(this, this.vendor, name, stringArray);  
}

我的 stringArray 值总是正确的,但它们被传递给错误的参数。通过修复我的参数和语句顺序,我的代码现在可以完全按预期工作:D

【讨论】:

    猜你喜欢
    • 2013-02-09
    • 2017-02-15
    • 2015-10-01
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多