JavaScript中使用.push()将多个对象添加到数组中返回“undefined”

19
当我向beats数组中添加项并控制台输出User时,得到的数组项数是正确的。但是当我检查.length属性时,总是得到1。 尝试调用索引将始终返回'undefined',例如:Tom.beats[1] 我认为我可能缺少一些显而易见的东西,但是这超出了我的能力范围。我怀疑我可能误用了.push方法,但我不确定。非常感谢任何帮助! (使用Chrome开发工具)
//The USER

function User(name, role){
    this.beats = [ ]; 

    this.name = name;
    this.role = role;

    // add beats to beats array

    this.addBeats = function(beats){ 
        return this.beats.push(beats);
   };

}

// Three New Instances. Three New Users.

var Mal = new User("Mal", "Rapper");
Mal.addBeats(["love", "cash"]);

var Dan = new User("Dan", "Producer");
Dan.addBeats(["cake", "dirt", "sally-mae"]);

var Tom = new User("Tom", "Producer");
Tom.addBeats(["Fun", "Little", "Samsung", "Turtle", "PC"]);

// Check for position in beats array

console.log(Tom.beats); 
console.log(Mal.beats); 
console.log(Dan.beats); 

console.log(Mal.beats[1]);
console.log(Dan.beats[1]);
console.log(Tom.beats[1]);

我想知道this指针在addBeats函数中是否混淆了。你能否在JS调试器中逐步执行它?(IE9有一个)。 - Dai
3个回答

52

Array.push(...)接受多个参数并将它们附加到列表末尾。如果您将它们放在一个数组中,那么这个“节拍”数组本身将被附加。

Array.concat(...)很可能不是您要寻找的,因为它会生成一个新的数组而不是将其附加到现有的数组。

您可以使用[].push.apply(Array, arg_list)来附加参数列表的项目:

this.addBeats = function(beats) { 
    return [].push.apply(this.beats, beats);
};

使用您的方法,现在它按照我的意图工作了。谢谢!所以,我的返回行完全不正确... - MFrazier
4
每次调用函数时,[].push 都会创建一个新的数组。我想使用 return this.beats.push.apply(this.beats, beats) 更加经济实惠。 - Alexander Kachkaev
2
@AlexanderKachkaev,实际上不是这样的:http://jsperf.com/nil-push/2。使用`[].someFunction.call`,`{}.someFunction.apply`等模式至少Firefox和Chrome可以理解和优化。使用`[].push`而不是`variable.push`或`Array.prototype.push`会更快一些,因为它不需要查找变量名。 - Kijewski
1
@Kay,如果jsperf也能提供内存消耗的概要就太好了。额外的百分之几的性能优势可能会被垃圾回收推迟到更晚的时间所抵消?(这种优化可能解释了为什么如果我将Gmail标签页保持打开几天,它占用的RAM比我的Java IDE还多?!) - David Bullock
2
注意:一年后我的说法不再正确。在Firefox v44和Chrome v46中,Array.prototype.push.apply的速度快了约10%左右。 - Kijewski

11

扩展运算符

在支持扩展运算符的环境中,您现在可以执行以下操作:

this.addBeats = function (beats) {
    return this.beats.push(...beats);
};

或者如果您需要更多的控制权,例如覆盖等

this.addBeats = function(beats) { 
    return this.beats.splice(this.beats.length, null, ...beats);
};

1

addBeats() 应该将 beats 参数与 this.beats 进行连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接