admin 管理员组文章数量: 1086019
I'm new to javascript, and came across the 'apply' method. As an exercise, I've tried to create a wrapper function for all functions, like the following snippet. 1. Why is this not working as expected, and 2. how can I create a wrapper function for all functions?
function funcWrapper(func){
return func.apply(this, arguments);
};
function sum(num1, num2){
return num1 + num2;
}
funcWrapper(sum, 2, 3);
// expected 5, but returns
// function sum(num1, num2){
// return num1 + num2;
// }2
I'm new to javascript, and came across the 'apply' method. As an exercise, I've tried to create a wrapper function for all functions, like the following snippet. 1. Why is this not working as expected, and 2. how can I create a wrapper function for all functions?
function funcWrapper(func){
return func.apply(this, arguments);
};
function sum(num1, num2){
return num1 + num2;
}
funcWrapper(sum, 2, 3);
// expected 5, but returns
// function sum(num1, num2){
// return num1 + num2;
// }2
Share
Improve this question
asked Oct 21, 2012 at 5:07
YeonhoYeonho
3,6235 gold badges40 silver badges62 bronze badges
1
-
1
Interesting, I never realized that doing
<function> + <number>
will convert the function into a string. JavaScript, always full of surprises. – Matt Greer Commented Oct 21, 2012 at 5:19
5 Answers
Reset to default 4It's because the arguments object in funcWrapper is [function sum(num1, num2){ return num1 + num2; }, 2, 3]
, the first argument is the function that you pass. The arguments
object is all of the arguments that you pass to the function.
The solution is to exclude the first argument which is the object. Usually in javascript, people use the slice method of the arrays. Well you might ask yourself that arguments
is an object, and doesn't have that method. But we can do the following workaround:
var args = Array.prototype.slice.call(arguments, 1);
return func.apply(this, args);
In the funcWrapper. Which again you make it shorter by converting the first line to this:
var args = [].slice.call(arguments, 1);
return func.apply(this, args);
You can also wrap that into a function like this:
function _slice(obj, start, end) {
return [].slice.call(obj, start, end);
}
And use it like this:
var args = _slice(arguments, 1);
Note that in ES6(Not implemented in browsers) this problem is solved by using rest parameters:
function funcWrapper(func, ...args){
return func.apply(this, args);
};
One more thing, that when you are trying to wrap constructors, make sure you also inherit the prototype too, or you fall into the same trap as this question: jQuery logger plugin
See this link here https://developer.mozilla/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments
"The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length. For example, it does not have the pop method. However it can be converted to a real Array:"
var args = Array.prototype.slice.call(arguments);
try
function funcWrapper(func){
var args = Array.prototype.slice.call(arguments, 1); // skip func parameter
return func.apply(this, args);
};
By giving the full arguments
object to .apply
, you're also giving the function.
You need to exclude the first argument.
function funcWrapper(func) {
var sliced = [].slice.call(arguments, 1);
return func.apply(this, sliced);
}
Another solution would be to do this:
function funcWrapper(func) {
return func.call.apply(func, arguments);
}
But that gets a little confusing.
Because arguments
contains [sum, 2, 3]
.
You would probably want to do this if you know the function to be called accepts 2 arguments:
return func.call(this, arguments[1], arguments[2]);
If you don't know the number of arguments, probably:
var args = [];
for(var i = 1; i < arguments.length; i++)
args.push(arguments[i]);
return func.apply(this, args);
return func.apply(this, arguments);
should be return func.apply(this, Array.prototype.slice.call( arguments, 1 ));
本文标签: javascriptapply() not working as expectedStack Overflow
版权声明:本文标题:javascript - apply() not working as expected - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744090005a2531853.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论