【问题标题】:push() not working in javascriptpush()在javascript中不起作用
【发布时间】:2013-09-04 15:57:24
【问题描述】:

问题:Uncaught TypeError: Object #<Object> has no method 'push' 在控制台中。

http://jsfiddle.net中的代码

【问题讨论】:

  • push 是数组的方法,而不是对象。
  • 您能否调试到appendToStorage 函数并查看从localStorage 加载后的oldStorage 对象?即通过 Chrome 的开发者工具。
  • @elclanrs 我猜 OP 知道这一点,因为他显然试图在首次访问时初始化数组 JSON.parse(localStorage.getItem(storageName)) || []
  • localStorage 中很有可能存在一个不是数组的值。尝试按照@Chips_100 的建议记录它或在浏览器开发工具中检查它。
  • 我用 IE 和 Chrome 中的小提琴测试了你的方法,它应该可以工作...jsfiddle.net/GHYMm

标签: javascript local-storage


【解决方案1】:

更改存储项 id(Cart) 并重试,看起来以前存储在“Cart”下的项目 id 不是 @dc5 在评论部分建议的 json 数组

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:"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
        BrandName:"General",
        ID:711
    };
    var item2 = {
        DepartmentID :123,
        CategoryID:321,
        BrandID:18,
        BrandImage:"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
        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;
}

【讨论】:

  • 对不起,我忘了提到QuantityInCart。请再次检查http://jsfiddle.net/vJkBQ/5/。
  • 我试过你的答案,当我在同一个项目上点击添加时,数量没有增加。
  • 你试过jsfiddle.net/vJkBQ/4吗?因为它对我有用,如果它不起作用,那你能写吗,控制台说什么
【解决方案2】:

表达式:

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 的存储格式可能与您预期的不同。

请在致电JSON.parse 之前先进行console.log(localStorage['Cart']) 并在此处发布您的结果。问题在于您浏览器上的您的本地存储,通常无法在其他人的计算机上复制。

【讨论】:

  • 这是对问题的正确且良好的解释 (+1)。但是 OP 还应该检查 localStorage 之前在密钥 Cart 下的内容,以及他是否在代码中的其他位置设置了它。否则这可能会导致细微的错误。
  • 如果即使不是数组也应使用旧值,则另一种选择是if (! (oldStorage instanceof Array) ) { oldStorage = [ oldStorage ]; }。
  • 请看我上面的jsfiddle,谢谢:)
【解决方案3】:

有

JSON.parse(localStorage.getItem(storageName)) 

总是返回一个数组?如果是这样,问题在于并非所有浏览器都支持 push 方法。如果缺少,您可以使用此 sn-p 添加它:

if(!Array.prototype.push){
    Array.prototype.push=function(x){
        this[this.length]=x;
        return true
    }
};

这段代码只是一个开始,你绝对可以改进它

【讨论】:

  • 我所知道的所有浏览器都支持 push,但是很好的建议:D
  • 哪个浏览器不支持Array#push?
  • 一些老版本的IE不支持,很多浏览器的实现都有一些怪癖。见hexmen.com/blog/2006/12/push-and-pop
【解决方案4】:

您可以使用 Array.prototype.push() 在使用 call() 的对象上调用。

JSFiddle

JavaScript

function appendToStorage(storageName, data){
    var oldStorage = JSON.parse(localStorage.getItem(storageName)) || [];
    Array.prototype.push.call(oldStorage, data);
    localStorage.setItem(storageName,JSON.stringify(oldStorage));
}

【讨论】:

  • 是的,你can。我不建议这样做,因为它很可能不会产生 OP 所期望的结果;或寻找...
  • 抱歉,我以为 OP 试图将数据推送到本地存储。
【解决方案5】:

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 对象。信息here

【讨论】:

  • 没有JSON object 这样的东西。你的意思是JSON.parse 总是会返回一个对象吗?情况并非如此,因为JSON.parse(null) 将返回 null。
【解决方案6】:

你的 'item' 不是一个数组,你不能对它使用 push 方法。

【讨论】:

  • 因为 OP 试图从数组开始,这可能没有帮助。JSON.parse(localStorage.getItem(storageName)) || [];
  • @Chips_100:这可能是正确的答案。否则push 会起作用。 JSON.parse(localStorage.getItem(storageName)) 很可能返回的不是数组。
  • 您的评论是正确答案。但是item 当然是一个对象,并且在 OP 的代码中从未调用过push。
【解决方案7】:

对象没有'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));
}

【讨论】:

  • 当 OP 试图用一个数组初始化时,它应该有一个 push 方法。现在你基本上做了一个改变,使它成为一个对象......
  • var push = Array.prototype.push;变量 obj = {}; push.call(obj, "你好");
猜你喜欢
  • 1970-01-01
  • 2016-02-26
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 2018-02-08
  • 2017-01-16
相关资源
最近更新 更多