Please have a look at this code. I need to show a alert message "mikä on elämän tarkoitus?" using this code
window["mikä"]("on")("elämän")("tarkoitus")("?");
I need to write a function or piece of code that will show that alert message when I will execute that code.
I have written a function like this:
window["mikä"] = function(str){
alert(str);
}
which works when I call window"mikä" but if I add more like below in console I see a type error.
window["mikä"]("on")("Hello")("How");
My question is would it be valid way to call like below as there is multiple function signs?
window["mikä"]("on")("elämän")("tarkoitus")("?")
To achieve the functionality you are looking for one way is to write a function which returns a function which returns a function as the others mentioned. That works fine if the number of functions is known before hand. Another way is to use a functional programming technique called currying, which is
the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application).
You can write your own curry function like this:
function curry(func, args_) {
var self = this;
self.args = args_ || [];
return function() {
var extended_args = [].concat(self.args).concat(Array.slice(arguments));
if(extended_args.length >= func.length)
return func.apply(this, extended_args);
return new curry(func, extended_args);
};
}
var funcName = "mikä";
window[funcName] = curry(functionstr1, str2, str3, str4) {
alert(funcName + ' ' + str1 + ' ' + str2 + ' ' + str3 + str4);
});
window["mikä"]("on")("elämän")("tarkoitus")("?");
Here are some resources which can help you if you are interested in learning more about currying / functional programming in JS.
http://kukuruku.co/hub/javascript/an-interesting-task-for-an-interview-currying-and-partial-applicationof-a-function
http://tech.pro/tutorial/2011/functional-javascript-part-4-function-currying
Reginald Braithwaite's talk in NDC Oslo
You want the return value to be a function as well, so that additional calls on the return value will call the same function. Just add this
window["mikä"] = function(str){
alert(str);
return window["mikä"];
}
EDIT: Misread your question, this will make multiple alert messages. Sorry.
You probably want to nest the function calls
window["mikä"] = function(s1){
return function(s2) {
return function(s3) {
alert(s1 + ' ' + s2 + ' ' + s3);
}
}
}
window["mikä"]("on")("elämän")("tarkoitus")("?");
As for getting the function name inside the function, there's really no good way to do that, and it should be avoided.
Related
I have been using functions as parameters. Now I need to pass a function A which requires parameters x generated by function B. I can do that too. by calling A in B with the parameters.
But my problem is, my function B accepts any kind of function, and it is not fixed. It may take function C also which requires parameter y or some function D that does not need any parameter.
Is this possible?
function B(done_function){
//some task generate some value
done_function();
}
function B(done_function){
//some task generate some value including args
done_function(args);
}
How can I make A, C and D functions execute with their arguments.
The top two examples won't work.
The normal way to handle this is to ignore it. Function B should simply not care about how other functions accept arguments. Instead it should only provide a standard and well documented interface to it's callback:
function B (done_function) {
// do some stuff to generate result
done_function(result);
}
Or if function B can possibly generate errors asynchronously then it should do done_function(err, result). Notice that all libraries do this. They don't care how you write your functions.
Now, how to pass various types of functions to B? Just wrap them around another function. For example, say you need to pass the result of B to a logger function and you need to pass a variable specifying the name of the file to log to. Just do this:
B(function(result) {
logToFile(debugLogFile, result);
});
Say for example you need to modify the result because the function you want to pass it to expect it to be in a specific format. Just do something like this:
B(function(result) {
var x = {
some_parameter: something,
result: result
};
doSomethingElse(x);
});
There is no scenario where function B needs to be aware of how you want to process the result it generates. It's you, the programmer, who is responsible to convert the result of function B appropriately before doing further processing.
You can make use of the functions call method:
function B(done_function){
//some task generate some value including args
done_function.call(done_function, args);
}
example jsfiddle
Let B call the callback with a single object as argument, which contains all information:
function B(done_function){
//some task generating some values, including args, for example:
var args = {
status: 3,
code: 'DEC',
location: 'Atlantic',
date: new Date('2017-01-01')
}
done_function(args);
}
Using ES6 destructuring in function parameters, you can filter out the information you need:
Function A could look like this:
function A({status}) {
console.log('status is ' + status);
}
B(A);
In the same way, C could look like this:
function C({code, date}) {
console.log('code is ' + code + ' on ' + date);
}
B(C);
Of course, ES6 destructuring is just a nice shortcut syntax, as you can do it also like this:
function A(response) {
console.log('status is ' + response.status);
}
B(A);
Alternative: use function's length property
If the distinction between different kinds of callbacks can be made on the basis of the number of parameters that are defined for them, then you could use the length property like this:
function B(done) {
var code = 'DEC';
var status = 1;
var location = 'Atlantic';
var date = new Date('2017-01-01');
switch (done.length) {
case 1:
done(status);
break;
case 2:
done(location, date);
break;
default:
done(code, status, location, date);
}
}
function A(status) {
console.log('status = ' + status);
}
function C(location, date) {
console.log('location = ' + location + ' on ' + date.toDateString());
}
B(A);
B(C);
Note the specific rules that apply for the length property's value.
I would like to know the best way to detect when a method or function is directly called through the console. As far as I currently understand, it's not possible to directly detect it on identical function calls, but using the .call() and .apply() methods of a function I can pass additional data through the this object.
Given the following code structure:
(function(){
var Player = {money: 0};
window.giveMoney = function(amount){
if (this.legit !== true)
throw new Error("Don't try to cheat!");
Player.money += amount;
}
})();
I could call the function using
window.giveMoney.call({legit: true}, 300);
in my actual code to tell a direct call from the console and my own code apart, but this is obviously not fool-proof, since the same code can also be executed from the console to achieve the desired effect.
I would want a way to be able to call the function from both places and then tell the locations of the call apart. If there's no way to do that, what's the best way to try and prevent the execution anyway? Is it best to just not expose any methods at all, and keep everything inside a single closed-off anonymous function?
To prevent global access make sure your code is in a closure. If you want to expose an API you can do so using the module pattern.
Closure
(function() {
var Game = {};
Game.giveMoney = function(money) {
console.log('Gave money (' + money + ')');
};
})();
Wrap all your private code in an IIFE (Immediately Invoked Function Expression) which will lock it up into a closure.
Module
Then expose only custom functions back out of the closure so you can use them on the console (with supervision of course).
window.Game = (function() {
var player = {
money: 500;
};
player.giveMoney = function(money) {
console.log('Gave money (' + money + ')');
player.money += money;
};
player.takeMoney = function(money) {
console.log('Took money (' + money + ')');
player.money -= money;
};
return {
giveMoney: function(money) {
console.error('Don\'t Cheat! A fine was charged.');
player.takeMoney(Math.floor(player.money / 0.05));
}
};
})();
window.Game.giveMoney(200);
You can spool all function calls through a central access point with a boolean variable, that can serve as a indicator whether the call is from a console or not....
var maths = {
add: function(p1,p2)
{
console.log(p1,p2);
}
}
var invoker = {
invoke: function(fu,isconsole)
{
if(isconsole)
{
console.log("Called from console");
}
//invokes the function with all parameters intact
fu;
}
}
//Call without console
invoker.invoke(maths.add(2,3));
//Call with console
invoker.invoke(maths.add(2,3),true);
Hope it helps!!!
You can use the monitor() command in the console to monitor when a function is called. https://developer.chrome.com/devtools/docs/commandline-api#monitorfunction
Just run monitor(functionName); and whenever the function is called it will output a message in the console.
I am a beginning JS programmer working through codeschool's 3rd JS course. One of their modules introduces the concept of passing function expression variables as parameters for other functions. However, I need some help understanding why this method is better in some cases than in others. For example, the following code is for a conditional alert that is supposed to recognize whether the user is a new user and throw a customized greeting when the user logs out of the system.
This is what codeschool advocates:
var greeting;
var newCustomer;
//Some code sets the variable newCustomer to true or false
if( newCustomer ){
greeting = function () {
alert("Thanks for visiting the Badlands!\n" +
"We hope your stay is...better than most.");
};
} else {
greeting = function () {
alert("Welcome back to the Badlands!\n" +
"Guess they aren't so bad huh?");
};
}
closeTerminal( greeting );
function closeTerminal( message ){ message();}
But why is that better than the following?
var greeting;
var newCustomer;
//Some code sets the variable newCustomer to true or false
closeTerminal();
function closeTerminal(){
if( newCustomer ) {
alert("Thanks for visiting the Badlands!\n" +
"We hope your stay is...better than most.");
} else {
alert("Welcome back to the Badlands!\n" +
"Guess they aren't so bad huh?");
}
}
Which of these code blocks (or any other code) would a good developer use to achieve the desired result? Is there an advantage to storing an entire function in a variable over just using a single if . . . else statement to evaluate newCustomer and return the desired greeting?
In your case, it is not inherently better.
But there are cases where it isn't this simple. Assume that you cannot modify the closeTerminal function, but its developer still wants you to execute arbitrary functionality from deep with his logic? That's where you use a callback function. Passing function expressions for them is only natural, but not strictly required. Have a look at purpose of callbacks in javascript maybe.
Another usecase for callbacks are asynchronous functions, you might encounter them later.
A better example might be
function closeTerminal(getMessage) {
var isNewCustomer = !Math.round(Math.random()); // complicated, local logic
var message = getMessage(isNewCustomer);
alert(message); // print to the closing terminal
// (which is local to this function as well)
}
You could invoke it with
closeTerminal(function greeting(newCustomer) {
// passing a custom function to determine the appropriate message
if (newCustomer)
return "Thanks for visiting the Badlands!\nWe hope your stay is...better than most.";
else
return "Welcome back to the Badlands!\nGuess they aren't so bad huh?";
});
Here's an example of their use:
function load_home() {
var url = "http://localhost/inner_load/page_test.html";
var method = "GET";
var postData = " ";
var async = true;
var request = new XMLHttpRequest();
/* Have a close look at this */
request.onload = function () {
var data = request.responseText;
Contenido.innerHTML=request.responseText;
}
request.open(method, url, async);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
request.send(postData);
}
As you can see, I can specify a function that defines an action that will be performed when the server returns a result. Another example would be:
function add(a, b) {
return a+b;
}
function mult(a, b) {
return a*b;
}
function calculate(func, a, b) {
return func(a, b);
}
In this case I can choose what to do with the values passed as a and b by passing a function as a parameter, if I pass add, the two numbers will be added, if I pass mult, they'd be multiplied.
calculate(add, 10, 5);
Will return 15. Where:
calculate(mult, 10, 5);
Would return 50.
This would save you a lot of trouble if you are doing, say, a calculator. Instead of using an if … else block and some var storing some integer numbers or strings to define the operations you want to perform, you could just call the function giving the operation you'd want to perform.
The concept of scalability and reusability. With your code it definitely works. For now. Any change requested from client would require you to modify a hell lot of code. While maintaining such granularity with functions, allows you to write code that works and works well.
I myself haven't gone through any codeschool tutorials but you might find Functions chapter in eloquent javascript interesting. Here is a link you can use.
In your version of the solution, you will always greet the user with only alert box. The version in the tutorial gives the caller of closeTerminal method the flexibilty to pass any method which can contain any logic. i.e show message in alert or in a new jquery ui dialog or bootstrap dialog or a completely different logic.
Please see the following code to understand how we can reuse your logic.
HTML
<div id="myDiv"></div>
Javascript
var greeting;
var newCustomer;
//Some code sets the variable newCustomer to true or false
if( newCustomer ){
greeting = function () {
alert("Thanks for visiting the Badlands!\n" +
"We hope your stay is...better than most.");
};
}else {
greeting = function () {
alert("Welcome back to the Badlands!\n" +
"Guess they aren't so bad huh?");
};
}
function closeTerminal( message ){ message();}
function divGreeting(){
document.getElementById('myDiv').innerHTML = "Thanks for visiting the Badlands!\n" +
"We hope your stay is...better than most."
}
closeTerminal( greeting );
closeTerminal( divGreeting );
Working sample - http://jsfiddle.net/7P2Ct/
Eric Miraglia of Yahoo/Google presents a very clean looking way to implement information hiding in JavaScript:
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
Please note some experiments here:
http://jsfiddle.net/TvsW6/5/
My question is, why can I access the seemingly "public" variable "this.setting2" (and of course not _setting1) YET I cannot access the function "this.logSetting_priv" although it is in the same scope as this.setting2 (isn't it!?!?!?) Does any one know why?
Also, with the use of the return object for the public methods, I can't seem to add a function as I might normally with "LogSystem.prototype.publicFunc1." Why is that?
Mystery of the ages . . .
Pls checkout my JSFiddle but the JS is also below:
function LogSystem() {
//default
var _divId = "log";
var _setting1 = "default stuff";
this.setting2 = "default stuff as well";; //This is accessible!
function _printLog(msg) {
msg = msg || "";
$("#" + _divId).append(msg + "<br/>");
};
//this is **not** accessible - bc of return object below?
this.logSetting_priv = function () {
_printLog("PRIV: Setting1 is: " + _setting1);
_printLog("PRIV: Setting2 is: " + this.setting2);
};
/*
* Key Distinguishing feature of this pattern
*/
return {
printLog: function (msg) {
console.log("PRINTING:" + msg);
_printLog(msg);
},
logSetting_pub: function () {
this.printLog("PUB: Setting1 is: " + _setting1);
this.printLog("PUB: Setting2 is: " + this.setting2);
},
publicFunc2: function () {
_setting1 = "Fixed Deal returnFunction";
this.setting2 = "floating hamster";
}
};
};
//THIS DOESNT WORK!! . . . . bc of the return object??
LogSystem.prototype.publicFunc1 = function () {
_setting1 = "Fixed Deal";
this.setting2 = "floating midget";
};
/*******************************/
/*********Testing Code**********/
/*******************************/
$(document).ready(function () {
var logInst = new LogSystem();
//TESTING METHODS!
try {
logInst.publicFunc1(); //THIS DOESNT WORK!!
} catch (e) {
logInst.printLog("The call to the prototype function does not work - WHY?");
logInst.publicFunc2();
}
try {
logInst.logSetting_pub();
logInst.logSetting_priv();
} catch (e) {
logInst.printLog("ERR!!: " + e.message);
}
//TESTING MEMBERS!
logInst.printLog("We know this does not work? " + logInst._setting1); //undef
logInst.printLog("Why Does THIS WORK? " + logInst.setting2); //def
});
Thank you!
EDIT: Holy crap - and when I manipulate the prototype of the INSTANCE variable, i seem to break the whole object that was returned: http://jsfiddle.net/TvsW6/7/
If any one understands JS at this level, PLEASE explain that! :)
Thank you all so much. Obviously any one in this conversation is at a level way beyond "I do some jQuery" :)
Using private instance variables prevents you from using prototype (functions that need to access them need to be in the constructor body where the privates are declared with var) at the end of this answer is link to a pattern that implements protected. It may take some time to understand how prototpe works and would advice trying to understand the basic workings first before trying to mix it with closures to simulate private/public modifier.
Pointy answered you question correctly that when invoking a function with new but then returning an object would not return the Object referred to as this in the function:
function Test(){
this.name="some test";
return {name:"something else"};
}
console.log((new Test()).name);//name:something else
Not returning an object or returning a primitive (string, boolean, number) would cause the this object to be returned:
function Test(){
this.name="some test";
return "hello";
}
console.log((new Test()).name);//name:some test
Your constructor is returning a different object than the one build implicitly with new. Thus, inside the constructor this refers to a different object than the one you actually end up with outside, and that object doesn't have a property called "logSetting_priv".
When you call a function in JavaScript and you miss to pass some parameter, nothing happens.
This makes the code harder to debug, so I would like to change that behavior.
I've seen
How best to determine if an argument is not sent to the JavaScript function
but I want a solution with a constant number of typed lines of code; not typing extra code for each function.
I've thought about automatically prefixing the code of all functions with that code, by modifying the constructor of the ("first-class") Function object.
Inspired by
Changing constructor in JavaScript
I've first tested whether I can change the constructor of the Function object, like this:
function Function2 () {
this.color = "white";
}
Function.prototype = new Function2();
f = new Function();
alert(f.color);
But it alerts "undefined" instead of "white", so it is not working, so I've don't further explored this technique.
Do you know any solution for this problem at any level? Hacking the guts of JavaScript would be OK but any other practical tip on how to find missing arguments would be OK as well.
If a function of yours requires certain arguments to be passed, you should check for those arguments specifically as part of the validation of the function.
Extending the Function object is not the best idea because many libraries rely on the behavior of defaulting arguments that are not passed (such as jQuery not passing anything to it's scoped undefined variable).
Two approaches I tend to use:
1) an argument is required for the function to work
var foo = function (requiredParam) {
if (typeof requiredParam === 'undefined') {
throw new Error('You must pass requiredParam to function Foo!');
}
// solve world hunger here
};
2) an argument not passed but can be defaulted to something (uses jQuery)
var foo = function (argumentObject) {
argumentObject = $.extend({
someArgument1: 'defaultValue1',
someArgument2: 'defaultValue2'
}, argumentObject || {});
// save the world from alien invaders here
};
As others have said, there are many reasons not to do this, but I know of a couple of ways, so I'll tell you how! For science!
This is the first, stolen from Gaby, give him an upvote! Here's a rough overview of how it works:
//example function
function thing(a, b, c) {
}
var functionPool = {} // create a variable to hold the original versions of the functions
for( var func in window ) // scan all items in window scope
{
if (typeof(window[func]) === 'function') // if item is a function
{
functionPool[func] = window[func]; // store the original to our global pool
(function(){ // create an closure to maintain function name
var functionName = func;
window[functionName] = function(){ // overwrite the function with our own version
var args = [].splice.call(arguments,0); // convert arguments to array
// do the logging before callling the method
if(functionPool[functionName].length > args.length)
throw "Not enough arguments for function " + functionName + " expected " + functionPool[functionName].length + " got " + args.length;
// call the original method but in the window scope, and return the results
return functionPool[functionName].apply(window, args );
// additional logging could take place here if we stored the return value ..
}
})();
}
}
thing(1,2 ,3); //fine
thing(1,2); //throws error
The second way:
Now there is another way to do this that I can't remember the details exactly, basically you overrride Function.prototype.call. But as it says in this question, this involves an infinite loop. So you need an untainted Function object to call, this is done by a trick of turning the variables into a string and then using eval to call the function in an untainted context! There's a really great snippet out the showing you how from the early days of the web, but alas I can't find it at the moment. There's a hack that's required to pass the variables properly and I think you may actually lose context, so it's pretty fragile.
Still, as stated, don't try and force javascript to do something against its nature, either trust your fellow programmers or supply defaults, as per all the other answers.
You can imitate something like Python’s decorators. This does require extra typing per function, though not extra lines.
function force(inner) {
return function() {
if (arguments.length === inner.length) {
return inner.apply(this, arguments);
} else {
throw "expected " + inner.length +
" arguments, got " + arguments.length;
}
}
}
var myFunc = force(function(foo, bar, baz) {
// ...
});
In general this sounds like a bad idea, because you’re basically messing with the language. Do you really forget to pass arguments that often?
You could use the decorator pattern. The following decorator allows you to specify minimum and maximum number of arguments that need to be passed and an optional error handler.
/* Wrap the function *f*, so that *error_callback* is called when the number
of passed arguments is not with range *nmin* to *nmax*. *error_callback*
may be ommited to make the wrapper just throw an error message.
The wrapped function is returned. */
function require_arguments(f, nmin, nmax, error_callback) {
if (!error_callback) {
error_callback = function(n, nmin, nmax) {
throw 'Expected arguments from ' + nmin + ' to ' + nmax + ' (' +
n + ' passed).';
}
}
function wrapper() {
var n_args = arguments.length;
console.log(n_args, nmin, nmax);
console.log((nmin <= 0) && (0 <= nmax));
if ((nmin <= n_args) && (n_args <= nmax)) {
return f.apply(this, arguments);
}
return error_callback(n_args, nmin, nmax);
}
for (e in f) {
wrapper[e] = f[e];
}
return wrapper;
}
var foo = require_arguments(function(a, b, c) {
/* .. */
}, 1, 3);
foo(1);
foo(1, 2);
foo(1, 2, 3);
foo(1, 2, 3, 4); // uncaught exception: Expected arguments from 1 to 3 (4 passed).
foo(); // uncaught exception: Expected arguments from 1 to 3 (0 passed).