I have been recently reading function expression and declaration in javascript and have referred to quite a few online articles about this. I also have seen quite a few discussion about this topic on SO. In the process of learning I tasked myself with a challenge, which I am not able to clearly explain.
Can I kindly request SO experts to help me gain some insight here?
Here is the problem scenario -
Scenario 1:
>var multFunc=function(n){var a=2; return n*a;}
>multFunc(6)
12
I understand this scenario and the result is what I was expecting (12).
Scenario 2:
>var multFunc1=function(n){return function(n){n*2}}
>multFunc1(6)
function (n){n*2}
I did not understand the second case. Why would it not return 12?
Can someone please help me understand this?
I have checked this link - Javascript Function Expressions, this link JavaScript Nested function
and I also did ask a similar question yesterday, but I guess I did not fully grasp the concept (as explained graciously by T.J) -
Trying a closure the wrong way?
The code:
var multFunc1=function(n){return function(n){n*2}}
returns a function. So multFunc1 represents the returned function, in this case:
function(n){n*2}
so you had to call like:
multFunc1(1)(2)
So basically the returned function remembers the value of n (passed argument, I recommend you to read about closures). So we can re-write the calls like:
var multFunc1=function(n){return function(x){n*x}}
var multBy2 = multFunc1(2)
var multBy16 = multFunc1(16)
multBy2(4) // 8
multBy16(2) // 32
Side note: The multFunc1's inner function, doesn't have any return statement, so it always returns undefined as #nnnnnn pointed out in comments
What you are essentially doing here in the second scenario is returning the function Object. Rather than returning the result of the execution of the function (which would be usually be 12) you are just returning the Reference to that object.
UPDATE:
I think you are missing the return statement inside the second function. By adding so, this yeilds the result I believe you are looking for.
var multFunc1=function(n){
return function(n){ return n*2}
}
// The first set of () require no argument as
// they are never used withing the second function.
multFunc1()(6);
Related
I am reading data from a serial port and with test case capturing the required output, then this output is sent to html
now while reading from serial port, there are few unicode charachters in the output.
I can remove them by using
.replace(/[^\x0000-\xFFFF]/g, "").trim();
there are approx 50 places where I need to use this replace and trim method, so I am trying to define a function, where I can pass the output to the function and it will give me clean output.
So I do not have to write .replace and .trim to every output.
here is what I tried till now.
This is the function I define to do the replace and trim.
function cleanoutput () {
var output = output.replace(/[^\x0000-\xFFFF]/g, "").trim();
}
This is the function calling to the output
display.adults = cleanoutput (adults.slice(28, 31));
By doing this I am getting error in function cleanoutput
error - "Cannot read property 'replace' of undefined"
I am just learning nodejs, need help on making this work.
There are two problems with your function: first, you are using replace on a variable that probably is not defined yet but is probably intended to work on a parameter, that is not defined either.
The second problem is that your function is not returning anything, so it is implicitly returning undefined.
display.adults will be undefined after the execution of the cleanoutput function.
You can fix those problems with something like this:
function cleanoutput (output) {
return output.replace(/[^\x0000-\xFFFF]/g, "").trim();
}
My suggestion is to dive a little bit deeper into javascript functions.
There are plenty of articles, blog posts, and youtube videos on the topic and I'm sure you will find a good one.
why this kind of bad design is made on js? Is there any special reason to design the automatic semicolon insertion like this?
Here is my code, It is not work in js in chrome:
(function(){console.log("abc");})()
(function(){console.log("123");})();
Here is the error:
Uncaught TypeError: (intermediate value)(...) is not a function
I know the right version of this code is :
(function(){console.log("abc");})();
(function(){console.log("123");})();
I just want to know why js syntax is designed so stupid. History reason?
I also add this question as a warning to everybody try to use the automatic semicolon insertion of javascript, please just add ; everywhere it needs, the automatic semicolon insertion of javascript is rubbish. It does not work as your expect.
The exist answer is too complex to my case, so I ask a new one:
https://stackoverflow.com/a/2846298/1586797
Another looks good but not work case 2:
x=1
(function(){console.log("123");})()
The linked question's answers explain the spec's three rules for ASI, for example this one. tl;dr:
If it doesn't work, try with semicolon.
The program should end with a semicolon.
If a statement says "can't put newline here", punish it with semicolon.
Your code does not satisfy any of the criteria.
The first line could return a function, and if so that function should be allowed to be invoked; so ( that the second line begins with is not illegal
The first line is not the last line of the program
There is no restricted syntax here.
Therefore, no automatic semicolon for you.
Some people have thus claimed that while (f(){})() syntax is good IIFE syntax, it might be good to do !f(){}() instead:
!function(){console.log("abc");}()
!function(){console.log("123");}();
This works as intended because ! just negates the (discarded) result of the function application, and also because ! as purely unary operator is an illegal character to continue the first line (i.e. f(){}()! is not a thing). This triggers rule 1, and ASI can take place.
The counterargument is that it is butt-ugly (i.e. for anyone not already familiar with the practice, it takes a while for them to understand the purpose of ! in this idiom).
Your second example is similar in nature: as far as the JS parser is concerned, 1 is a value (the fact that it is an integer and could not possibly be a function is a bit lost to it). Look at this example that syntactically is completely equivalent to yours:
a=function(f) { console.log("A CALLED!"); return f; }
x=a
(function(){console.log("123");})()
# => A CALLED!
123
Here, a is a function, so it can be invoked with function(){console.log("123");} as an argument; it returns function(){console.log("123");} unchanged after printing to the console; then () invokes that return value, and 123 is printed as well. Everything works. Thus, Rule #1 is not triggered, no semicolon for you.
(function(){console.log("abc");})()
(function(){console.log("123");})();
is equivalent to:
(function(){console.log("abc");})()(function(){console.log("123");})();
And is what is usually referred to as function currying.
For IIFEs (immediately invoked function expressions) you need to end with ;
For more on function currying see this post. Obviously your console log functions do not work as currying functions, but the syntax yourFunction(a)(b)(c) is a cool feature of the language that is used for currying.
Your code can be simplified as:
(function(){})()()();
This code will get same error.
The () expect a expression to call.
The first () call the (function(){}), the second () call the (function(){})()'s result, but the result is not a function, so it's wrong.
Without the semicolon those statements are chained. You call the first function and give the second func as argument to the return value of the first one. This could actually work, if the first function had a function as return value.
When you expand the code it becomes more obvious:
var a = function(){console.log("abc");};
var b = function(){console.log("123");}
(a)()
(b)();
the last two lines become:
(a)()(b)();
this is equivalent to
var x = a();
x(b);
since a does not return anything, it cannot call it as function with b as argument.
I think this will be clearer if you use this:
x=1
(function(){console.log("123");})()
The error states 1 is not a function. Makes it clear that (function...) is treated like the argument of a function call to 1:
x=1(function(){console.log("123");})()
Because ()() is self-invoking function and ();() are two differnt functions and interpreter is interpreting it accordingly.
Here two pieces of code are totally different for an interpreter.
(function(){console.log("abc");})()(function(){console.log("123");})();
and
(function(){console.log("abc");})();(function(){console.log("123");})();
however, this code will work fine
var a=12
var b=10
console.log(a+b)
Long answer sort :
(function(){console.log("abc");})()
is trying to immediately-invoke the preceding expression which is
(function(){console.log("123");})();
Which would be the return value of the preceding IIFE.
IIFEs can act differently in the missing semicolon situation. That is why we see code as follows:
;(function() {
console.log('abc');
})()
Please have a look of details description here : https://gist.github.com/khellang/8518964
I don't know how to phrase it properly so I can't find answers by Google, but here's basically my problem:
I want my CoffeeScript to output something like this in JS: (I'm developing a Node app)
var someapp = require('someapp')
var another = require('another')
someapp.configure(function() {
someapp.use(another.do('argument'));
});
So I wrote it this way in CoffeeScript:
someapp = require 'someapp'
another = require 'another'
someapp.configure () ->
someapp.use another.do 'argument'
But instead, I'm getting this output:
some.configure(function() {
return someapp.use(another["do"]('argument'));
});
Obviously, my biggest problem is the line return someapp.use(another["do"]('argument')); I can't find in the CoffeeScript docs or elsewhere the proper syntax, so I'm hoping someone can point me to the right direction. Thanks in advance.
According to the docs,
CoffeeScript provides the do keyword, which immediately invokes a passed function, forwarding any arguments.
So, coffeescript outputs another["do"] to avoid using the do reserved keyword.
Furthermore, in this case, the function another.do is an object property that happens to be a function. It can be accessed by using both another.do() and another["do"]().
Excuse me first. because i don't know this is question is valid or not. i if any one clear my doubt then i am happy.
Basically : what is the different between calling a method like:
object.methodname();
$('#element').methodname();
calling both way is working, but what is the different between, in which criteria make first and second type of methods. is it available in the core javascript as well?
In case if i have a function is it possible to make 2 type of method call always?
Can any one give some good reference to understand correctly?
Thanks in advance.
The first syntax:
object.methodName();
Says to call a function, methodName(), that is defined as a property of object.
The second syntax:
$('#element').methodname();
Says to call a function called $() which (in order for this to work) must return an object and then call methodname() on that returned object.
You said that "calling both way is working," - so presumably you've got some code something like this:
var myObject = $('#element');
myObject.methodname();
This concept of storing the result of the $() function in a variable is commonly called "caching" the jQuery object, and is more efficient if you plan to call a lot of methods on that object because every time you call the jQuery $() function it creates another jQuery object.
"Is it available in the core javascript as well?" Yes, if you implement functions that return objects. That is, JS supports this (it would have to, since jQuery is just a JS library) but it doesn't happen automatically, you have to write appropriate function code. For example:
function getObject() {
return {
myMethod1 : function() { alert("myMethod1"); return this; },
myMethod2 : function() { alert("myMethod2"); return this; }
};
}
getObject().myMethod1().myMethod2();
In my opinion explaining this concept in more depth is beyond the scope of a Stack Overflow answer - you need to read some JavaScript tutorials. MDN's Working With Objects article is a good place to start once you have learned the JS fundamentals (it could be argued that working with objects is a JS fundamental, but obviously I mean even more fundamental stuff than that).
The difference is very subtle.
object.methodname();
This is when JavaScript has the object at hand.
$('#element').methodname();
If you are using jQuery, you are asking jQuery to select the object that has the id of #element. After that you invoke the method on the selected object.
This question already has answers here:
What does javascript function return in the absence of a return statement?
(3 answers)
Closed 7 years ago.
If I have a javascript function, it is possible that I do not return a value from every code path, e.g:
function f()
{
if (checkSomething())
{
return 42;
}
// no return statement here
}
Is this valid javascript or does it only work by chance (i.e. might there be problems when run in some browsers)?
Yes, it is valid javascript. If checkSomething() evaluates to false, it will return undefined.
See http://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope for more details.
Althought, you should note that returning different types of data (In this case, an integer or undefined) is bad practice.
Since Javascript is a loose language compared to compiled ones, you can get away with things that most compiled languages will not allow. So yes, it can be done, it's just a matter of whether you want to do something like this. If you were to try to compile this code in a language such as C# or similar, the compiler would generate an error.
I am not trying to critique your code, just offering a suggestion on good design. Functions are intended to return values on all code paths and it is up to the calling code to check that return value and decide what to do. You could check the return value for undefined or whatever it is when checkSomething() returns false or you could set the value to something more meaningful that the calling code can check upon return. You may have return values that mean certain things to the caller. -1 means one thing, -2 means something else.
Hope this helps.
This JavaScript will work, just keep in mind that if you try to read the return value of f it will be set to undefined if no return statement is executed.
Personally I think this code is a little weird. If you are going to return from one code path, I suggest returning from all other possible code paths as well. That way someone reading and working with your code knows exactly what to expect.