原型回调函数替换'这'价值
Prototype callback function replace 'this' value
好吧,我偷偷怀疑我忽略了一些非常简单的东西,但我对以下代码有问题:
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;
}
好吧,简而言之,这个函数类似于排序函数,只是它通过多级对象进行排序,并且我指定它需要按哪些键进行排序。
问题是,我从来没有实际替换或更改"this"值,这意味着这个函数实际上什么都不做。例如:
var arr = new Array(new Array(1,5),new Array(2,0));
arr.sortArr(1);
它不会在sortArr(1)
调用之前或之后更改arr
。然而,当我把alert(newArr)
放在函数返回之前时,它表明它确实重新排序了。所以,我的问题是;如何替换回调函数中的this
值,或者至少返回正确的/新的数组?提前谢谢。
要在方法结束时修改当前数组,您需要像这样分配给它的元素,在函数结束前将所有元素复制到当前对象的数组中:
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循环,就像我在上面的代码片段中所做的那样。
实现后,将返回一个新数组。如果你想用新的结果替换原来的数组,你必须明确地这样做:
var arr = new Array(new Array(1,5),new Array(2,0));
arr = arr.sortArr(1);
但听起来这不是你想做的。
var newArray = [{},"Bob",32].sortArr();
不要把你的return语句看作是回到函数的顶部。。。…把它想象成从左手边出去。
因此,当你定义你的函数时,你把你的参数放在你的参数的位置。如果要按原样对传入的对象进行排序,则需要对原始对象as-is执行操作,而不保存对象的副本。
我的意思是:
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将向原始对象添加名称:"Bob"。
function addBob2 (obj) {
bobject = obj;
bobject.name = "Bob";
return undefined; // again, if you don't state a return, that's what you get
}
好的。现在我们遇到了一个问题。你能看到吗?
您已经将一个对象放在函数的顶部,并保存了对象的本地副本(有时,这是一件好事…但不是在这里)。
然后你修改了你的副本。
你以为你完了。但你不是。一切都没有改变。为什么?
因为您没有将更改保存回原始版本。可能有两种方法:
函数addBob3(obj){var localObj=obj;localObj.name="Bob";obj=localObj;}
addBob3(externalObj);
该函数用于保存本地副本以进行计算,但一旦完成这些计算,它就会覆盖原始对象或对象的属性,即:
obj.name = localObj.name;
这将把数据发送回原始对象(即:从函数顶部)。有些人认为这种做法很糟糕,因为如果你有几十个这样的就地修改函数,当你进入10000行程序时,很难判断哪些对象被哪些函数修改了。
现在不要太担心。
其他方法:
function addBob4(obj) {
var localObj = obj;
localObj.name = "Bob";
return localObj;
}
var externalObj = { property1 : "something" },
newObj = addBob4(externalObj);
现在,返回值将输出到函数调用的LEFT。newObj将是一个与externalObj完全相似的对象,除了您对副本进行的新添加。
因此,如果在变量中捕获返回,函数可以从左边退出。如果直接修改传入的对象,在函数退出后,这些编辑将应用于原始对象。
处理"这个"有点棘手。如果它是一个对象,您只需执行"this.name=‘Bob’;"即可完成。
在数组的情况下,您需要第三个循环,基本上清空this[0]-this.length-1],然后用newArr中的值填充this[0]–this[newArr.length-1]。因为JavaScript不会让你把"this"分解成"this=X"语句。
- AngularJS:我可以跳过函数参数回调吗
- 要求未定义JS回调参数
- MeteorJS:在带有回调的vzaar api上正确使用wrapAsync
- 自引用回调
- 测试Angular Service解决错误回调中的promise
- 如何将一个JavaScript函数回调为多个函数
- JavaScript回调函数
- 用于回调的javascript参数
- 将json回调数据转换为日期
- 承诺在非节点式回调上使用Bluebird
- 如何在回调函数中执行流
- 回调函数中传递参数的困难(Google Map API Markers)
- Soundcloud Javascript SDK 3.0-回调无法读取属性'connectCallback
- 如何使用jqueryAJAX从页面中回调多个变量
- jquery Onclick函数带有导致双击的回调排序函数
- Javascript点击事件回调不起作用
- 一旦加载并渲染了角度引导typeahead,就使用回调
- 成功回调永远不会被JSONP请求调用
- 如何让程序员在javascript中实现正确的回调
- 原型回调函数替换'这'价值