问题:Uncaught TypeError: Object #<Object> has no method 'push'
在控制台中。
7 回答
更改存储项目 id(Cart) 并重试,看起来以前存储在“购物车”下的项目 id 不是 json 数组,正如评论部分中建议的 @dc5
UPD:试试这个http://jsfiddle.net/vJkBQ/4/
HTML
<div id='cart'></div>
<input type="button" id="add" value="Add To Cart item 1" />
<input type="button" id="add2" value="Add To Cart item 2" />
Javascript
//TODO: move from globals
var storageName = 'myCART';
$(document).ready(function () {
var item = {
DepartmentID :333,
CategoryID:117,
BrandID:19,
BrandImage:" ",
BrandName:"General",
ID:711
};
var item2 = {
DepartmentID :123,
CategoryID:321,
BrandID:18,
BrandImage:" ",
BrandName:"Common",
ID:712
};
localStorage.clear(storageName);
$('#add').click(function(){
addToCart(item);
});
$('#add2').click(function(){
addToCart(item2);
});
});
function addToCart(item){
//by @slebetman
var items = JSON.parse(localStorage.getItem(storageName));
if (! (items instanceof Array) ) {
items = [];
}
var itemIndex = getItemIndexById(items, item.ID);
if(typeof(itemIndex) === 'number'){
items[itemIndex].quantity++;
}
else{
item.quantity = 1;
items.push(item);
}
localStorage.setItem(storageName, JSON.stringify(items));
console.log(localStorage.getItem(storageName));
}
//find search item index
function getItemIndexById(items, id){
for(var i = 0; i < items.length; i++){
if(items[i].ID == id){
return i;
}
}
return false;
}
表达方式:
JSON.parse(localStorage.getItem(storageName))
很可能不会返回数组。在这种情况下,声明:
var oldStorage = JSON.parse(localStorage.getItem(storageName)) || [];
是不够的。
你应该做的是这样的:
var oldStorage = JSON.parse(localStorage.getItem(storageName));
if (! (oldStorage instanceof Array) ) {
oldStorage = [];
}
这是一种检测数组的简单方法。还有更高级的方法,例如检查是否存在.length
等,可以检测数组和类似数组的对象,以及在 Array 对象已被覆盖或跨 iframe 工作的情况下检测数组。
补充回答:
您已经更改了很多代码,但问题仍然相同。该行:
if (items != null) {
不足以检查 items 是一个数组。你应该这样做:
if ( items instanceof Array ) {
以确保它确实是一个数组。
此外,在 else 块中:
}else{
console.log('Cart is empty, preparing new cart array');
items.push(item);
console.log
消息说正在准备一个新阵列。然而,它的存在是因为代码没有初始化一个新数组,而是items
像使用数组一样使用变量。你应该这样做:
}else{
console.log('Cart is empty, preparing new cart array');
items = [];
items.push(item);
警告:
但是,毕竟,请注意我的问题的评论者。如果你从头开始写这整件事,而不是做我建议的事情会解决你所有的问题。但是,如果您正在做的是修改其他人的代码,那么很可能Cart
是以不同于您预期的格式存储的。
请console.log(localStorage['Cart'])
在致电之前做,JSON.parse
并在此处发布您的结果。问题在于您浏览器上的本地存储,通常无法在其他人的机器上复制。
做
JSON.parse(localStorage.getItem(storageName))
总是返回一个数组?如果是这样,问题在于并非所有浏览器都支持 push 方法。如果缺少,您可以使用此代码段添加它:
if(!Array.prototype.push){
Array.prototype.push=function(x){
this[this.length]=x;
return true
}
};
这段代码只是一个开始,你绝对可以改进它
你可以使用你可以调用Array.prototype.push()
一个对象使用call()
.
JavaScript
function appendToStorage(storageName, data){
var oldStorage = JSON.parse(localStorage.getItem(storageName)) || [];
Array.prototype.push.call(oldStorage, data);
localStorage.setItem(storageName,JSON.stringify(oldStorage));
}
JSON.parse
返回一个对象或null
. 所以在这里你不知道你有一个对象还是一个数组。
JSON.parse(localStorage.getItem(storageName)) || [];
您可以改用它:
function appendToStorage(storageName, data){
var oldStorage = JSON.parse(localStorage.getItem(storageName)) || {};
if (oldStorage != null){
$(oldStorage).extend(data);
localStorage.setItem(storageName,JSON.stringify(oldStorage));
}
}
$.extend() 会将您的项目添加到另一个 JSON 对象。信息在这里
您的“项目”不是数组,您不能对它使用推送方法。
对象没有'push'方法,你可以这样做!
function appendToStorage( storageName, data ) {
var oldStorage = JSON.parse( localStorage.getItem( storageName ) ) || {},
push = Array.prototype.push;
push.call( oldStorage, data );
// oldStorage.data = data;
localStorage.setItem(storageName,JSON.stringify(oldStorage));
}