通过原型链

时间:2017-07-21 19:24:21

标签: javascript inheritance parameters prototype undefined

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

出于某种原因, stringArray 的类型在 Child.prototype.setText 时会从对象更改为未定义 移动到继承的 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未定义

1 个答案:

答案 0 :(得分:0)

(感谢JoelCDoyle在评论中提醒我声明顺序很重要!)

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

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

/* 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;
}

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

所以,当JoelCDoyle提到我的儿童属性需要移到家长电话之上时,我会将它们复制到它上面。那是我注意到这个问题并纠正它的时候:

/* 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