JavaScript异常:不是一个函数

时间:2017-02-26 17:08:27

标签: javascript arrays json object local-storage

我在JavaScript中创建了两个对象原型。这些是对象构造函数。您可以看到Board对象包含PostIt个对象的数组:

function PostIt(id, msg, img, pos) {
  this.id = id;
  this.msg = msg;
  this.img = img;
  this.pos = pos.slice(); // copy of array
}

function Board() {
  this.postIts = [];   // Empty array of PostIt objects
} 

每个原型都有自己的方法(getter / setter),Board也有方法从数组中推送和弹出PostIt对象。

我还在Board中实施了一个机制来保存&通过localStorage检索数组:

Board.prototype.save = function () {
  // Clean localstorage first
  localStorage.clear();

  if (this.getNumPostIts() > 0) { // It array is not empty
    localStorage.setItem('myboard', JSON.stringify(this.postIts));
  }
};

// Retrieve array of postit objects from local storage
Board.prototype.load = function () {
  this.postIts = JSON.parse((localStorage.getItem('myboard')));
};

正确检索PostIt对象,但是当我将它们分配给Board对象的this.postIts数组时,我不确定会发生什么:

this.postIts = JSON.parse((localStorage.getItem('myboard')));

一旦我在加载网站时这样做了,当我尝试为数组中的任何postit对象调用方法时,我得到一个异常。例如,加载文档后的以下代码

myBoard = new Board();

if (localStorage.myboard) { // Local Storage has data
  // Retrieve data from local storate and dump it to myBoard
  myBoard.load();

  // Display Id for every postit
  for (var i=0; i < myBoard.getNumPostIts(); i++) {
    var pId = myBoard.getPostItByArrayIndex(i).getId();
    console.log("PostIt #%d has id = %d", i, pId);
  }    
} 

调用PostIt对象的getId()方法会引发异常: jQuery.Deferred异常:myBoard.getPostItByArrayIndex(...)。getId不是函数TypeError:myBoard.getPostItByArrayIndex(...)。getId不是函数

我不明白为什么“getId”不是函数。当我调用这个getter方法时有什么问题吗? 编辑: .getId()是PostIt对象原型的getter方法:

PostIt.prototype.getId = function() {
  return this.id;
};

1 个答案:

答案 0 :(得分:2)

JSON格式不存储您转换为JSON的对象的原型。因此,当您再次解析这些JSON字符串时,对象将只是普通对象,与原型无关,如getId。因此,像PostIt这样的原型方法不再适用于那些对象。

同样,您也会丢失对象的直接方法,因为JSON没有为函数格式提供。

如何使其发挥作用

我首先要更改pos构造函数,以便它具有所有参数的默认值。更具体地说,它需要对function PostIt(id, msg, img, pos) { this.id = id; this.msg = msg; this.img = img; this.pos = Array.isArray(pos) ? pos.slice() : []; // default is empty array } 属性进行一些调整:

Object.assign

现在您可以使用PostIt将JSON解析对象转换回Board.prototype.load = function () { this.postIts = JSON.parse((localStorage.getItem('myboard'))) .map(x => Object.assign(new PostIt, x)); }; 个对象:

{{1}}