I have a JavaScript function:
function oneOf() {
return arguments[Math.floor(Math.random()*arguments.length)];
}
It is designed to take in variable number of arguments and spit out a random one, and this works. I can't get it to take a list of object methods and execute one. How would I do this?
Function.prototype.apply
allows you to "splat" an array into the arguments list:
function sayAll() {
console.log(arguments);
}
sayAll(1, 2, 3, 4);
// [1, 2, 3, 4]
sayAll.apply(null, ["a", "b", "c"])
// ["a", "b", "c"]
Functions can be invoked with parenthesis (see above).
Combining these two insights, we get the following:
function oneOf() {
var f = arguments[Math.floor(Math.random()*arguments.length)];
return f(); // Via insight #2
}
// Via insight #1
oneOf.apply(null, [someFunction, anotherFunction]);
If these functions are "methods" on an object and need to retain their this
context, then we'll need a third insight.
Function.prototype.bind
allows creating a function with a fixed this
context:
function sayWhatThisIs() {
console.log("This is", this);
}
var coolObject = {
cool: true,
sayWhat: sayWhatThisIs
};
coolObject.sayWhat();
// This is {cool: true, ...}
oneOf.apply(null, [coolObject.sayWhat.bind(coolObject),
sayWhatThisIs.bind(coolObject)]);
// Two variations of binding `sayWhatThisIs` to `coolObject`
We could also pass on the this
context of oneOf
to Function.prototype.apply
:
function oneOf() {
var f = arguments[Math.floor(Math.random()*arguments.length)];
return f.apply(this);
}
onOf.apply(coolObject, [coolObject.sayWhat, sayWhatThisIs]);
// Now applying insight #3a to set `onOf`'s `this` context to `coolObject`.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.