admin管理员组文章数量:1334133
I'm reading javascript the good parts, and the author gives an example that goes like so:
['d','c','b','a'].sort(function(a,b) {
return a.localeCompare(b);
});
Which behaves as expected. Now I have tried to do something like this - which is the next logical step:
['d','c','b','a'].sort(String.prototype.localeCompare.call);
And that fails with an error:
TypeError: object is not a function
Now I left wondering why... Any ideas?
I'm reading javascript the good parts, and the author gives an example that goes like so:
['d','c','b','a'].sort(function(a,b) {
return a.localeCompare(b);
});
Which behaves as expected. Now I have tried to do something like this - which is the next logical step:
['d','c','b','a'].sort(String.prototype.localeCompare.call);
And that fails with an error:
TypeError: object is not a function
Now I left wondering why... Any ideas?
Share Improve this question asked Dec 11, 2011 at 1:20 Leon FedotovLeon Fedotov 7,8715 gold badges31 silver badges33 bronze badges4 Answers
Reset to default 6call
needs to be bound to localeCompare
:
['d','c','b','a'].sort(Function.prototype.call.bind(String.prototype.localeCompare));
The reason you are having a problem is that you are passing sort
Function.prototype.call
. As you may know, when no this
is otherwise provided, it will be the global object (window
in browser environments). Thus, when sort
tries to call the function passed to it, it will be calling call
with this
set to the global object, which in most (all?) cases is not a function. Therefore, you must bind call
so this
is always localeCompare
.
The reason it doesn't work is that String.prototype.localeCompare.call
returns a reference to Function.prototype.call
not to String.prototype.localeCompare
as you might think.
You're passing a reference to the call
function without retaining any relationship to the localeCompare
method you intend it to be called upon. So sort
will invoke the function referenced byString.prototype.localeCompare.call
, but it will invoke it in the global context, not as the method of some function object.
As @icktoofay pointed out, you need to bind the call
function to localeCompare
. Here's a much oversimplified demonstration of how this is done without the bind
method:
function simpleBind(fn, _this) {
return function() {
return fn.apply(_this, arguments);
}
}
['d','c','b','a'].sort(simpleBind(Function.prototype.call,
String.prototype.localeCompare));
Ok, solved it! this does the trick:
['d','x','z','a'].sort(String.prototype.localeCompare.call.bind(String.prototype.localeCompare))
Cause when you think about it the sort function actually calls apply on call so it needs to be bound to the string object in order to execute in scope. ^_^
本文标签: javascriptWhy does call does not work as A sort functionStack Overflow
版权声明:本文标题:javascript - Why does call does not work as A sort function? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742367437a2461571.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论