好吧,我怀疑我忽略了一些非常简单的事情,但是我遇到了以下代码的问题:
Array.prototype.sortArr = function (skey)
{
var vals = new Array();
for (key in this)
{
if (typeof(this[key][skey]) != 'undefined')
{
vals.push((this[key][skey]+'').toLowerCase());
}
}
vals.sort();
var newArr = new Array();
for (i=0;i<vals.length;i++)
{
for (key in this)
{
if (typeof(this[key][skey]) != 'undefined')
{
if ((this[key][skey]+'').toLowerCase() == vals[i])
{
newArr.push(this[key]);
break;
}
}
}
}
return newArr;
}
好的,简而言之,这个函数类似于sort函数,但它通过多级对象进行排序,并指定需要排序的键。
问题是我从来没有真正替换或改变'this'值,这意味着这个函数实际上没有做任何事情。例如:
var arr = new Array(new Array(1,5),new Array(2,0));
arr.sortArr(1);
它不会在arr
来电之前或之后更改sortArr(1)
。但是,当我在函数返回之前放置alert(newArr)
时,它表明它确实重新排序。所以,我的问题是;如何替换回调函数中的this
值或至少返回正确/新数组?提前谢谢。
答案 0 :(得分:1)
要修改方法末尾的当前数组,您需要分配给它的元素,在函数结束之前将所有元素复制到当前对象的数组中:
this.length = newArr.length;
for (var i = 0; i < newArr.length; i++) {
this[i] = newArr[i];
}
你也可以像这样使用.splice()
:
newArr.unshift(this.length); // how many items to remove for .splice()
newArr.unshift(0); // index for .splice() operation
this.splice.apply(this, newArr); // add the newArr elements
仅供参考,在数组上使用for/in
构造通常不正确,因为除了数组元素之外,它还将迭代对象上的属性,这通常会使你犯规。如果你想迭代数组中的项目,请使用传统的for循环,就像我在上面的代码片段中所做的那样。
答案 1 :(得分:0)
实现后,您将返回一个新阵列。如果要用新结果替换原始数组,则必须明确地这样做:
var arr = new Array(new Array(1,5),new Array(2,0));
arr = arr.sortArr(1);
但听起来这不是你想做的事。
答案 2 :(得分:0)
var newArray = [{},"Bob",32].sortArr();
认为你的退货声明不是回到功能的顶部...... ......把它想象成离开左手边。
因此,当您定义函数时,将参数放在参数的位置。 如果要按原样对要传入的对象进行排序,则需要按原样对原始对象进行操作,而不保存对象的副本。
我的意思是:
function addBob (obj) {
obj.name = "Bob";
return undefined;
// any fn without a return mentioned returns undefined, anyway.
// I just put this here for reference.
}
此版本的addBob将添加名称:&#34; Bob&#34;到原始对象。
function addBob2 (obj) {
bobject = obj;
bobject.name = "Bob";
return undefined; // again, if you don't state a return, that's what you get
}
好。现在我们遇到了问题。 你能看到吗?
您已将对象放入功能的顶部,并且您已保存对象的本地副本(有时,这是一件好事......但不是在这里)。
然后你修改了副本。
你认为你已经完成了。但你不是。没有改变。 为什么呢?
因为您没有将更改保存回原始版本。 可以有两种方法:
function addBob3(obj){ var localObj = obj; localObj.name =&#34; Bob&#34 ;; obj = localObj; }
addBob3(externalObj);
此函数用于保存本地副本以进行计算,但是一旦完成这些计算,它就会写入原始对象或对象的属性 - 即:
obj.name = localObj.name;
这会将数据发送回原始对象(即:从函数顶部开始)。 有些人认为这是一种不好的做法,因为如果你有几十种这样的就地修改功能,当你进入10,000行程序时,很难分辨哪些对象被哪些功能修改过。
现在不要太在意这件事。
OTHER 的方式:
function addBob4(obj) {
var localObj = obj;
localObj.name = "Bob";
return localObj;
}
var externalObj = { property1 : "something" },
newObj = addBob4(externalObj);
现在,您已经获得了函数调用的 LEFT 的返回值。 newObj将成为一个与externalObj完全相同的对象,除了你对副本的新增内容。
因此,如果捕获变量中的返回值,函数可以从左侧退出。 如果您直接修改传入的对象,就会在函数退出后将这些编辑应用于原始对象/对象。
使用&#34;这个&#34;有点棘手。 如果它是一个对象,你可以这样做,这就是&#34; this.name =&#39; Bob&#39 ;;&#34;而且你已经完成了。
对于你的数组,你需要第三个循环,你基本上清空这个[0] - 这[this.length - 1],然后填充这个[0] - 这个[newArr。 length - 1],来自newArr的值。 因为JavaScript不会让你爆炸&#34;这个&#34;把它变成&#34;这= X&#34;言。