I just bought the newest version of "JavaScript: The Definitive Guide" and already have a question. :D
Are the following lines semantically the same:
var square = function(n){
return n * n;
};
and
function square(n){
return n * n;
}
If yes, what are the advantages/disadvantages of using either of them?
Thanks for your help!
Check this out:
a(); // prints 'A'
function a(){
console.log('A');
};
and this:
b(); // throws error. b is not a function
var b = function() {
console.log('B');
};
Did you notice the difference?
Yes, they do the exact same thing.
The main advantage of the first approach is that it gives you a reference to that function so that you could pass it to another function or attach it to an object if you need to.
Difference is that in the first solution, you can do that :
var square = function(n){
return n * n;
};
// some code
square = function(n) { return n*n*n; }
you have reference to a function. On the other solution, the function is statically declared.
Disclaimer: need JS guru to tell me if I'm wrong =).
Related
I'm studying JavaScript from the book JavaScript: The Good Parts, in the memoization section there is an example about using memoize technique to do Fibonacci problem
We create a general function call memoizer, it takes an memo array and the fundamental function, returns a shell function that manages the memo and calls fundamental function
var memoizer = function(memo, fundamental) {
var shell = function(n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
And then create fibonacci like this:
var fibonacci = memoizer([0, 1], function(shell, n) {
return shell(n-1) + shell(n-2);
});
If I run fibonacci(10), the result will be displayed exactly.
But the thing that makes me confused is the n parameter shell function in memoizer function. I know that it is the value that we want to compute. But where is it come from? How can I call fibonacci(10), for example, can pass the value 10 to n? And what is exactly the var fibonacci? Is it a function or points to a function object as memoizer?
Thanks for any help!
So, to understand this fully, you need to understand things below as fundamental pieces.
Closure How do JavaScript closures work?
Scope What is the scope of variables in JavaScript?
First class object What is meant by 'first class object'?
So, now look at the code.
var memoizer is assigned as a function that returns an another function inside.
var memoizer = function(memo, fundamental) {
var shell = function(n) {
... do some works ...
};
return shell;
};
Can you see it? var shell is returned at the end of the line in memoizer
And whatever the inner logic is in memoizer, the result of it is assigned to var fibonacci
var fibonacci = memoizer([0, 1], function(shell, n) {
return shell(n-1) + shell(n-2);
});
So, it means fibonacci equals the result of memoizer (Since we excuted it), and the result of memoizer equals shell function. If you read those links given to you by me well, you can understand what is going on behind the scenes.
By the way, the code you've given isn't the best way. Because anyway closure makes an activated object alive that isn't necessary.
This code below is an another way of making fibonacci, this isn't the absolute best way, however, I recommend you to compare this code with your code, and figure the differences out.
var result = [];
result[0] = 1;
result[1] = 1;
function fibonacci(n){
var i;
for(i = 2; i < n; i++){
if(!result[i]){
result[i] = result[i-1] + result[i-2];
}
}
return result[i-1];
}
console.log(fibonacci(10));
I have so far:
function func(f,x) {
alert(f(x));
}
func(function(x) {return x*x;},2);
This works, but i am thinking that passing function(x) {return x*x;}, is excessive and I could just pass x*x, as the idea is that I can supply (pretty much) any function.
I have tried:
function func(f,y) {
g=function() {return f;};
alert(g(y));
}
func(x*x,2);
amongst others, but I can't get it to work. Perhaps if I passed 'x*x' as a string..?
You're correct that the syntax is excessive, but for ES5 and before, that's just how it is.
However, in ES6 you can use the new "arrow function" lambda syntax:
func(x => x * x, 2);
See http://www.es6fiddle.net/i4o5uj2l/
FWIW, the above func isn't great since it only supports unary functions, i.e. those taking a single parameter. You could expand func to use ES6 "spread arguments":
function func(f, ...args) {
console.log(f.apply(this, args));
}
func((x, y) => x * y, 3, 7);
> 21
Well I have a way to do that using eval here http://jsfiddle.net/q5ayoszy/
function func(f,y) {
g=function()
{ x=y;
return eval(f);
};
alert(g(y));
}
func('x*x',2);
Note : I pass the expression as a string and then use it inside the function.
You just need to assign the value of y to the variable x inside the function so the eval evaluates correctly
The only way to do that with a string is by using the infamous eval: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
var x = 2;
var y = eval("x * x"); //y = 4
But using eval is almost always a very bad idea.
You could use currying to break down the process into smaller functions:
function multiply(x) {
return function() {
return x*x;
}
}
var bytwo = multiply(2);
bytwo(); // 4
How to get the the variable name from within a function in this example:
// it should return A
var A = function(){ console.log(this.name); }
Is there something like this?
That function is anonymous; it has no name. You could, however, give it a name:
var A = function a() {};
Then its name is accessible via Function.name:
var A = function a() {};
A.name
> 'a'
I know this is an old thread, but still in search results. so just for reference:
a solution could simply be using the stacktrace.
var stack = new Error().stack;
use trim and split to get to the desired values.
No, there is nothing like that in Javascript. That function is anonymous, so it has no name, and what you want is ambiguous because the function could just as easily have any number of variables referencing it like:
var a, b, c, d;
a = b = function(){ console.log(this.name); };
c = b;
d = c;
a = b = 5;
// a and b no longer refer to the function, but c and d both do
What is it you are actually trying to accomplish? I'm sure there is another way to achieve it.
It is possible in recent versions of Chrome and Firefox as follows. I only recommend this for debugging purposes (e.g. javascript tracing in non-production)
var myNameInChrome = /.*Object\.(.*)\s\(/.exec(new Error().stack)[0];
var myNameInFF = new Error().stack.split("#")[0];
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between (function(){})(); and function(){}();
I am trying to understand a few of the features of JavaScript a little better. In The Definitive JavaScript it says that self-executing functions should have brackets round them like so:
var obj = (function() {
var value = 0;
return {
increment: function(inc) {
value += typeof inc === "number" ? inc : 1;
},
getValue: function() {
return value;
}
}
})();
but in JavaScript - The Good Parts where this example is taken from, it has the above self-executing function without the brackets round, like so:
var obj = function() {
var value = 0;
return {
increment: function(inc) {
value += typeof inc === "number" ? inc : 1;
},
getValue: function() {
return value;
}
}
}();
Both of these examples work for me, but I wanted to ask if there were any differences in functionality that I should be aware of. I hope this isn't too trivial. I just wanted to be sure.
Thanks a lot.
Edit:
As Rob W has pointed out, there is another thread on the subject. This is an excellent blog regarding this issue that was linked to from the other post.
There isn't any difference in this case, but only because it's prefixed with:
var obj = ...
Without that, only the first version is correct, because you need the additional parentheses to allow the interpreter to correctly parse the function as a function expression and not as a function declaration.
You would of course only omit var obj if you only want the function to run (i.e. you want its side effects) but it either returns no value, or you don't care what its return value is.
JavaScript: The Good Parts was written by Doug Crockford, who has updated his example to look like this:
var obj = (function() {
var value = 0;
return {
increment: function(inc) {
value += typeof inc === "number" ? inc : 1;
},
getValue: function() {
return value;
}
};
}());
So the whole expression is within the brackets.
The idea of the outside brackets, which are not required, is that it makes it clear to developers that this is an intentionally self-executed function. So the value is readability.
There aren't, in this example, any functional differences, but I do think the parentheses make it much more readable. How do you know how it is scoped without the parens? Is it hoisted? This is a brilliant thread on the subject.
ASIDE:
JSLint will complain that "function statements are not invocable. Wrap the whole function invocation in parens." I think most browser parsers not running in strict-mode would generally let it pass, but it's better not to rely on that.
I am still fighting my battle against my low IQ :D
This is the usual infamous cycle with closures:
function r(){
var a = [];
var i;
for(i=0;i<10;i++){
a[i]=(function(x){
return function(){return x;}
})(i);
return a;
}
This is quite clear to me now.
In order to understand closures better, I played with the code and came up with:
function r(){
var a = [];
var i;
for(i=0;i<10;i++){
a[i] = (function(){
var x=i;
return function(){return x;}
})();
}
return a;
}
Is my code fully equivalent?
Merc.
Is my code fully equivalent?
Yes.
I find it slightly easier to read the second way, because it saves having to look to the end of the immediately-executed function to find out what's passed in as a parameter (not that that's a big problem with short functions like this), but the first way is more compact and probably more common so...
I guess you didn't try them, the first one doesn't even work! Use firebug to test your code. Here is a version of the first example which actually doesn't give errors:
function r() {
var a = [];
var i;
for (i=0; i<10; i++) {
a[i] = (function (x) {
return function () {
return x;
}
})(i);
}
return a;
}
So, after adding the missing closing brace, they are equivalent, they build an array of functions that return the numbers from 0 to 9, they don't build an array of numbers from 0 to 9. So for example, calling r()[5](); returns 5 (is the sixth element of the array).