I was experimenting on alert but alert dosen't worked as i expected have look below lines:
var tobealerted = function(){return 'worked!'};
now when i alert this:
alert(tobealerted());
this will work fine! now
alert(tobealerted);
in this i removed parentheses. now it alert function(){return "worked"} not worked!
now i thought it may be a feature of javascript that it would alert any text without being in quotes then i wrote:
alert(worked!)
but the google console throw exception worked! is undefined , so my thinking was wrong. then again i wrote this
alert(function(){})
and you know what it alerted function(){}! and then i thought that alert would only allow such statement to be alerted without quotes. then again wrote:
alert(if(){}) //if is not defined
alert(for(){}) //for is not defined
alert(while(){}) //while is not define
but these did not worked for this i searched and found something, from my search i found this
functions are first class object
and according to wikipedia:
In computer science, a programming language is said to have
first-class functions if it treats functions as first-class citizens.
Specifically, this means the language supports passing functions as
arguments to other functions, returning them as the values from other
functions, and assigning them to variables or storing them in data
structures
so my question is
why did alert function only allowed function (){} to be alerted but not others
and if you think it is because that function is a first-class object then i don't think so because
i did not assign this function(last one) to any variable neither it returns anything in alert(function(){})
i am so much curious and also confused!
thanks!
You gave the answer yourself. Functions are objects and as such have toString() functions. The other examples you gave are statements, not objects.
As noted by others, window.alert() only displays String objects and triggers the toString() function of any other type of object. It expects anything you feed it to be an object or a reference to an object.
This is what happened when you were trying to alert those statements; it assumed if etc. were variable names, but it couldn't find any reference by that name.
alert converts its argument to a string. That's all.
> x = function() { }
function () { }
> x.toString()
"function () { }"
You can't invoke toString() on an if/for/while as those expressions don't resolve to values.
Function is just another type of object in Javascript, so:
alert(tobealerted());
alerts the function result but:
alert(tobealerted);
alerts the function object itself using .toString() method which returns function's body for objects of type function.
Statements like if and so on are not objects but full definition of function declares an object. So you can alert function and not if statement for example.
If you want the alert to return a value it must be in quotes like this:
alert('worked!');
If you want it to display a value returned from a function, it must be called as a function:
alert(tobealerted());
If you call a function without the parenthesis, you are basically asking for the definition of the function and because functions are first-class, it will allow you to assign it to a variable.
The if/for/while are conditional operators so they don't work the same as a user-defined function. They have a very specific use and aren't meant to be overrode.
When you tried alert(function(){}); it was no different from you trying to assign the function to a variable. The function definition was stored, but you didn't actually invoke the function. Now if you did alert(function(){}());you would have actually invoked the function and it would have alerted undefined. It is all a matter of defining vs invoking.
Related
I'm curious why:
(function () { return 'one' })()()
returns:
TypeError: (intermediate value)(...) is not a function
and not:
TypeError: 'one' is not a function
Error messages use variable names or other identities to say what is not a function. Because the return value hasn't been assigned to anything, it doesn't have an identifier, so the engine says intermediate value
The documentation of the error message "TypeError: "x" is not a function" explains:
What went wrong?
It attempted to call a value from a function, but the value is not actually a function. Some code expects you to provide a function, but that didn't happen.
It also provides some code examples that triggers this error and the actual error message reported by them. I won't copy them here but please take a closer look on them and notice the error messages they generate.
The "x" part is replaced in the actual error messages by the name of the object that is expected to be a function and it is not.
Because the object in this case does not have a name (it is an intermediate result computed during the evaluation of the expression, see the explanation below), the engine cannot report its name and tries to be as helpful as it can. It reports "(intermediate value)(...)" probably because this way it is more descriptive; it is a value returned by a function that is not stored but used for computation of another value.
It cannot report the actual value instead because the intermediate value can be anything; if it is a complex data structure then the error message becomes bloated without adding much information.
Apparently I didn't understand the question from the first time, what follows is my initial answer that explains why the error is generated, not why the error message is what it is and not what the OP expects.
This code ...
(function () { return 'one' })()()
... creates an anonymous function...
function () { return 'one' }
... calls it...
(function () { return 'one' })()
... then attempts to interpret the value returned by the function as another function and call it:
(function () { return 'one' })()()
The function created on step #1 returns a string ('one') when it is invoked (on step #2).
On step #3, the effect of the code is the same as calling 'one'(). This is not the same as one() (as you might think).
The intermediate value referred in the error message is the string returned by the first function call that is then used in the expression (as a function) without being saved in a variable (that's the explanation of the "intermediate" wording.)
As the error message clearly says, 'one' is not a function and attempting to use it as a function (by placing the second pair of parenthesis in the expression) doesn't work.
In order to make it work, the anonymous function created on step #1 must return another (anonymous) function, like this:
(function() { return function() { return 'one'; } })()()
Now, when it is called, the outer function returns an anonymous function that is similar with the anonymous function created on step #1 by the original code. When this function is called (the second ()) it returns the string 'one'.
This is probably not what you wanted. Calling a function given its name as string is possible only by using eval() which is language feature that is best to avoid (for several strong reasons.)
Because when in braces () it (function () { return 'one' }) becomes an expression which yields intermediate results and those results are not yet bound to a variable yet.
As per spec,
Specification type values are specification artefacts that do not
necessarily correspond to any specific entity within an ECMAScript
implementation.
Specification type values may be used to describe intermediate results
of ECMAScript expression evaluation but such values cannot be stored
as properties of objects or values of ECMAScript language variables.
Before asking, I have tried to do my homework and to avoid a duplicate. Thus, I have read about 20 questions and answers (mainly on SO) which all deal with toString(). But unfortunately, none of them did answer my actual question. So here we go ...
Many examples contain code like that:
Object.prototype.toString.call(someVariable);
I just would like to know why toString can be used like a property here. I have read the reference for Object.prototype at MDN and other places. All of them list a function toString() among the members of Object.prototype, but no property toString.
Furthermore, I am using a line like that shown above at several places in my code. For testing purposes, I have added parentheses to make it "clean":
Object.prototype.toString().call(someVariable);
Obviously, that did not make it "clean", but just made it return wrong results or even made the browser stall (I am currently in the process of researching what exactly is going on).
I already have read some questions and answers regarding calling functions without parentheses. But even if I accept that the first of the code lines shown above actually calls a function (although it looks like accessing a property), that still does not explain why it goes wrong horribly when I add the parentheses as shown in the second code line. Being able to call functions without parentheses should not mean being unable to call them with parentheses, should it?
I don't think that question has an answer already (if yes, I apologize), so could anybody please give a short explanation?
Is Object.prototype.toString a function or a property?
Object.prototype.toString is a property. The value of that property is a reference to a function. Exactly like this:
var obj = {f: function() { } };
There, obj.f is a property, the value of which is a reference to a function.
The initial value of Object.prototype.toString is the intrinsic function known in the spec as %ObjProto_toString%. It can be overwritten, but doing so would like break a lot of things.
The thing to remember is that in JavaScript, functions are just objects that inherit from Function.prototype* and are callable. Just like other objects, you can keep references to them in properties and variables (you can even add properties to functions themselves), pass those references around, etc. This is in marked contrast to many languages which treat "classes" and methods and other kinds of functions as special, non-object things.
* (host-provided objects aren't required to inherit from Function.prototype, but in modern environments most do; in some obsolete browsers, some don't.)
Functions are just values. toString is a property of the Object.prototype object whose value is a function.
() is the function call operator. Object.prototype.toString doesn't call a function; it just fetches the value of the Object.prototype.toString property (which happens to be a function).
Functions are also objects, with properties of their own. That's why you can do Object.prototype.toString.call(...): This gets the Object.prototype.toString function, then fetches its call property, then calls it (which is allowed because the value of call is another function).
This works even without involving properties:
var foo = function () { return "hello"; };
var bar = foo;
console.log(bar);
console.log(bar());
The first line assigns a function value to the foo variable.
The second line assigns the same value to bar, reading from foo. Note that we're not calling the function, we're just passing it around like any other value.
The first console.log displays the function itself.
The second console.log displays the result of calling the function, because we used ().
Welcome to JavaScript. It's true that functions can be called without () in some cases (specifically, new f), but not in this case. What you see is the reference to the function being used as an object but not called (yet). That's a common thing to do, although in this case it's probably a bit more obscure than usual so I'll explain why it's done like that.
The function finally gets called when you explicitly call its call method (every function inherits that from the Function prototype), which allows you to bind this in the function body to some arbitrary object. Your first example may do the same thing as someVariable.toString(). So why use the longer formĀ ?
Well, someVariable may not have a toString method (if it's null or undefined, because they are not objects and can't be boxed into an object), in which case using someVariable.toString would throw a TypeError. Or its prototypal toString method may have a different behaviour than the one for basic Objects. In this case, I guess that the author wanted to use an old-school trick for getting the name of an object's "species", which involves the fact that Object.prototype.toString always returns "[Object whatever]" where "whatever" will be the constructor's name or Null or Undefined.
In this article js log function, there is a statement:
Function.prototype.apply.call(console.log, console, arguments);
I'm really confused by this statement.
What does it do?
How can I analyse this statement?
Or with some thoughts or tools, I can figure it out step by step?
Can it be simplified to more statements to achieve the same result? for instance: var temp = Function.prototype.call(console.log, console, arguments); Function.prototype.apply(temp);
Thanks for the response.
Apply is a function on the function prototype. Call is also a function on the function prototype. Apply is a function, therefore, it has call on it's prototype. All this is doing is calling the apply function.
Read more about apply here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
What does it do?
It calls console.log with console as this during the call, passing along the arguments in the
pseudo-array arguments as discrete arguments to the function.
So if arguments had "hi", "there" in it, it would be the same as:
console.log("hi", "there");
How can I analyse this statement?
Or with some thoughts or tools, I can figure it out step by step?
Let's start with what the apply and call functions are: They each have the ability to call a function
using a specific this during the call and passing arguments to that function. apply gets those
arguments from a single array (or anything array-like). call gets those arguments as individual arguments.
Normally, you'd see apply or call used like this:
someFunction.apply(valueForThis, ["arg1", "arg2", "arg3"]);
// or
someFunction.call(valueForThis, "arg1", "arg2", "arg3");
The only difference between apply and call is how they expect to get their arguments (apply = in
an array-like thing, call = as individual arguments).
So why, then, isn't that code doing this?
console.log.apply(console, arguments);
It's being cautious: console.log is a function provided by the host. It may not be a true JavaScript
function, and so it may not have the apply property.
So that code is avoiding relying on console.log having the apply property.
Which is where Function.prototype comes in. It's a reference to the object that is the prototype of all true JavaScript functions.
That prototype is where the apply and call properties on JavaScript functions come from.
So if we're worried that console.log doesn't have it (e.g., in case it doesn't inherit from Function.prototype), we can grab apply from that prototype object directly.
So the code is using call to call apply, and using apply to call console.log.
Can it be simplified to more statements to achieve the same result?
Not really, there's not a lot we can separate. I'll try to use variable names to clarify:
var thisValue = console;
var functionToCall = console.log;
var applyFunction = Function.prototype.apply;
applyFunction.call(functionToCall, thisValue, arguments);
Let's take this one part at a time.
Function.prototype.apply, more commonly seen as myBigFatFunction.apply, lets you call a function with a different this context than it would normally have. The difference between apply and call is that the former takes an array of arguments, the latter takes direct arguments after the first. Example:
myStr.substring(5)
String.prototype.substring.apply(myStr, [5]);
String.prototype.substring.call(myStr, 5);
^ all equivalent
However, for reasons I can't fully explain myself, some browser-native functions accessible to JavaScript don't have this function as a property (eg, console.log.apply). It's still possible to manually call it in the same manner though; so that console is still this, when it calls log, and that's what the given function is doing.
The reason for all that complication is that they want to pass in the arguments special variable. This is a keyword that exists in all functions, which represents all arguments to the function as an array-like object (so, suitable for Function.prototype.apply)
Your variable suggestion would likely simply call console.log once with console as argument one, and arguments as variable two, and return the result, rather than give you a function in a variable. If you want a shortened reference, it's possible you could use Function.prototype.bind, but that could actually lengthen your code.
I have just found that I can define a function in JavaScript like this:
function a(){ ([]()) }
and similarly, this way is also a valid function definition.
function a(){ ([]())()()([])([]) }
It doesn't even look like a valid syntax, doesn't it? But the compiler doesn't blame when define them. (Surely invoking a() will cause you an error later)
A function of an empty array? A function of a function of an empty array, or something? I can't even understand how this is considered valid to be defined as a function in JavaScript compiler.
In case you're curious: Not all these kind of function definitions will pass the compiler. You may try defining this below.
function a(){ ([]())()()([])([]){} }
JS compiler won't let you define it.
I know the function will not be able to invoke, but to my wondering, I can define it. So I'm eager to know why this is valid to define.
[] creates an empty array. It's not a function, so treating it as a function by calling it like []() will give a runtime error, but there's nothing syntactically invalid about it.
And wrapping stuff in parentheses, [] vs. ([]), has no effect when used on its own like that, but again it's valid syntax.
Try running a(), you will get a runtime error.
The thing is, when you define a function (like what you did), the function obviously won't be executed so any runtime error will not be reported (since the engine has no way of knowing a runtime error except by actually running the function).
EDIT:
In response to the author's comment, imagine this function:
function a(){ (alert()) }
which is syntactically similar to the first function. However this function is perfectly fine - no runtime errors.
That's why the engine allows you to define functions like this. In order for the engine to catch the problem in function a(){ ([]()) }, it has to make the inference "[] is an array, which is not callable, so this function generates an error". However, calling an uncallable object is a runtime error (TypeError) so the engine will not make the said inference - as that would be trying to catch a runtime error at compile-time.
P.S.: Calling an uncallable object is not necessarily a runtime error in other languages. In most strictly-typed language that is a compile-time error. If you do in Java int[] x; x();, that would generate a compile-time error.
As to the second function, you need to understand the concept of higher-order functions. If you don't know what that is, I will do a simple explanation here.
Imagine this:
function addone(x){return x+1;}
function f(){return addone;}
now if you run f()(1), that is equivalent to addone(1), which is 2.
Now f is a second-order function, you can define a third-order function:
function g(){return f;}
Then g()()(1) is again 2. If you want, you can define a hundredth-order function. Though in real code you rarely need more than second-order.
Now back to the second function in the OP:
function a(){ ([]())()()([])([]) }
You are trying to run [] as a fifth-order function, which is syntactically perfectly fine. Again, checking whether [] is actually a fifth-order function is a runtime thing.
Please note down.
1) A JavaScript function returns undefined (if there is no return statement define) even if there is nothing inside function.
2) Similiary ()()()([])([]) is valid. Because there is no any syntax error. Code inside functions are validated for syntax error inside validator e.g. there should be no code after () except semicolor ; or () etc. All type error will be validated only at execution.
3) This is valid but when you call this function, It will throw uncaught typerror
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Javascript: var functionName = function() {} vs function functionName() {}
Way 1:
function fancy_function(){
// Fancy stuff happening here
}
Way 2:
var fancy_function = function(){
// Fancy stuff happening here, too.
}
I use the former when I'm just defining a "normal" function that I'm gonna use one or several times and the latter when I'm passing it a callback for another function or so, but it looks to work fine in the both ways.
Is it really a difference in some way?
There is no difference to the function itself, but the latter gives you more flexibility as you have a reference to the function and it is different with regard to how it behaves if overwritten.
This allows you to achieve behaviours with the latter that you cannot achieve with the former; such as the following trick to "override" an existing function and then call the "base":
var myOriginalFunction = function() {
window.alert("original");
}
var original = myOriginalFunction;
var myOriginalFunction = function() {
window.alert("overridden");
original();
}
myOriginalFunction();
This gives you an alert "overridden", followed by an alert "original".
However, if you attempt this with the former notation, you'll find you get stuck in a never ending loop of alert "overidden".
In the first sample you are defining a named function -- that function will always be known by that name. Defining a different function with the same name will be an error (unless you assign to the window property directly). In the second sample, you are defining an anonymous function and assigning it as the value of a variable. You can change the value of the variable to any other function later as desired; losing, of course, any reference to the anonymous function in the process unless you've stored it elsewhere. So, you're not really doing the same thing in both cases, though you can treat it that way if you wish -- and make sure to define the function before it's used in the second case, though that's more a function of variables than functions per se.
function definition
function literal assignment
only difference is you can access the former instantly in certain cases whereas you have to wait for the assignment on the latter.
Don't run this in firebug console/interpreter to test it, rather test on a real html page.
say('spotted');
function say(msg){ alert(msg) }
The above will work, but if you defined a function literal with var say = function(){} below, it would complain that it isn't defined yet.
You can use either depending on the situation, both become the methods of the window object. The later is known as anonymous function.
As far as the function is concerned, they will behave identically.
See here for more details: http://javascript.about.com/library/blfunc.htm
Functions defined with the Function(){} style are available throughout the program, without having to be defined earlier in the code than where they are called. It's called 'hoisting', I believe.
so this works
cow('spotted');
function cow(color){ return 'cow is '+color; }
but this throws an error
cow('spotted');//cow isn't defined yet!
var cow=function(color){ return 'cow is '+color; }