Javascript Evaluation Questions (Part 2) - javascript

(function () {
var x = 5;
(function () {
function f(y) { return (x+y)-2 };
(function () {
function g(h) { var x = 7; return h(x) };
(function () { var x=10; z=g(f); })();
})();
})();
})();
I'm working through some problems from my textbook in my class to prepare for our next exam, and can't figure out how the above evaluates.
Mostly, I don't understand the call z=g(f), as when f is evaluated, it isn't provided an argument, so how does it evaluate at all? How does it know what y is? What would g(f) evaluate to?
Also, as far as scoping goes, I believe javascript treats most everything as global variables, so the last x that is set would be the x value used in function f, correct?
Thanks for any help!
Please note, these are extra problems in the back of the book I'm practicing to prepare for the exam, these are not direct homework questions.

In this case of g(f) the function f is not evaluated but instead is passed as an object / value. Functions are values in javascript and can be passed as such. The function g later evaluates the function f via the expression h(x) (because f is passed as the parameter h)
Here's a more direct example
var addOne = function(x) { return x+1; }
var f = addOne;
var value = f(4); // Returns 5

It helps to have better formatting and indentation so that it's easier to investigate what's happening:
(function() {
var x = 5;
(function() {
function f(y) { // <-- y is the x from function g
return (x + y) - 2
};
(function() {
function g(h) {
var x = 7; // <-- local x is defined and passed to f
return h(x) // <-- h === f
};
(function() {
var x = 10;
z = g(f); // <-- f is passed to g
})()
})()
})()
})()

Variables defined within functions are scoped to that function. You should probably figure out the rest from there if this is really for a class.

Mostly, I don't understand the call
z=g(f), as when f is evaluated, it
isn't provided an argument, so how
does it evaluate at all? How does it
know what y is? What would g(f)
evaluate to?
If you look at how g is implemented:
function g(h) { var x = 7; return h(x) };
It takes an argument h, which is a Function, and then calls it as h(x). I hope this helps you understand how z = g(f) ends up running function f.
Also, as far as scoping goes, I
believe javascript treats most
everything as global variables, so the
last x that is set would be the x
value used in function f, correct?
Incorrect. When the var statement is used, a new variable in the local scope is defined. In your case, the final x is not global.

I also beautified it for readability.
(function () {
var x = 5;
This sets a local variable x to 5.
(function () {
function f(y) {
return (x + y) - 2
};
This creates a local function f; note that the above x (currently 5) is closed in.
(function () {
function g(h) {
var x = 7;
return h(x)
};
We define a function g that takes a function h as a parameter. It has a local variable x, which shadows the other one.
(function () {
var x = 10;
z = g(f);
})()
This x is a red herring; it shadows the outer one, and is never actually used. We then call g, passing f. Going above to g, we see that f becomes formal parameter h, and is called with 7. In f, that becomes y. So we get (5 + 7) - 2, 10. Due to the shadowing, it is not equivalent to the other code.
The outer x is never modified, just shadowed.

Related

How this function passes arguments to another inner function parameters

When i check MDN to learn some points about closures, i faced the below function.
It can be a known pattern in javascript, but it's strange for java or .NET developer.
I want to know how it works, i know about arguments and first class object behavior in javascript language but how add5(2) assigned 2 to y variable.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
First, any time there are named parameters - there is an implicit variable declaration. So forget the function above, just consider this
var example = function() {
var x = 5;
return function(y) {
return x + y;
}
}
var inner = example();
console.log(inner(5));
> '10'
Do you understand how the above works? if not I'd recommend looking into javascript closure and what it means.
Javascript Closures
In the above function makeAdder, the only difference is that we are passing the value of x. But x is still defined in the outer function, and the resulting returned function closes over its value
The function makeAdder returns a function, so the variables add5 and add10 are just references to functions. When you call those functions with a parameter vale, that ends up as the parameter y in the function.
You can do the same in C# for example, and the closure works the same:
public static Func<int, int> MakeAdder(int x) {
return y => x + y;
}
Using it:
Func<int, int> add5 = MakeAdder(5);
Func<int, int> add10 = MakeAdder(10);
Console.WriteLine(add5(2));
Console.WeiteLine(add10(2));
makeAdder returns a function which can be seen like:
var x = 5;
function add5(y){
return x + y;
}
makeAdder(5) called the function makeAdder, with x bound to 5. This function returns another function. Furthermore, since the value of x was provided, the anonymous function inside makeAdder knows the value of x. At this point in time, makeAdder will return:
function(y) {
return 5 + y;
}
Therefore, by assigning this new function to add5, add5 is now a function, as well. If we call add5(2), it will use the above function, and perform the following:
function(2) {
return 5 + 2;
}
Which will output 7.
How does this work?
The function defined in the closure 'remembers' the environment in
which it was created.
ref

Is it possible to use inner functions in JavaScript?

How can I get access to my y() function?
function x() {
function y() {
return 1;
}
}
Is it possible at all?
It is scoped to x, kind of like:
function x() {
var y;
}
So, yes, from within x, and no otherwise.
If you wanted it to be, you could create it as a property on x:
var x = (function () {
function x() {
…
}
function y() {
…
}
x.y = y;
return x;
})();
You mean access it from outside the function x?
That's not possible, the function y doesn't exist when x is not running. It's declared locally inside x so it's only accessible inside x.
To make it accessible outside x you need to expose a reference to it outside the function. If you expose a reference to it, it survives after the function ends. For example:
function x() {
function y() {
return 1;
}
return y;
}
// get the reference to y
var f = x();
// call y
f();
You can get access to your y function inside of the scope of the x function Only.
But you can get access to the y function if you return it from your x function or assign it to a global variable or to the variable that is in scope outside of your x function. This is also know is closure, your y function will keep the reference in memory to the scope it was created in if you pass it around.
function x() {
var anotherNum= 2;
function y() {
return 1 + anotherNum;
}
return y;
}
Now you can get the y function along with the scope it was created in. Notice that it will use anotherNum in the computation as it was created in the x function.
var yFunc = x();
console.log(yFunc()) // will print 3
One way is to return it out of the scope
function x() {
function y() {
return 1;
}
return {
y:y
};
}
Whenever you call x(), it returns an object with the function y as a member
var a = x();
a.y(); //this returns 1
This is similar to the revealing module pattern described here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FClosures
Also good to read up on closures:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FClosures

javascript error because of global scope variables

var x = 3;
(function (){
console.log('before', x);
var x = 7;
console.log('after', x);
return ;
})();
In the above code var X is initialized globally. So inside the function the first console.log should print "before 3" but i don't get it. The reason is that i am trying to re-declare the global variable.
Can somebody explain why this is happening?
In the above code var X is initialized globally. so inside the function the first console.log should print "before 3".
No, it should print before undefined, because var takes effect from the beginning of the function regardless of where you write it.
Your code is exactly the same as this:
var x = 3;
(function (){
var x;
console.log('before', x);
x = 7;
console.log('after', x);
return ;
})();
And of course, variables start with the value undefined.
Details: Poor misunderstood var
The JavaScript parser does Variable Hoisting when parsing your code. This means that any variable declaration will be moved to the top of the current scope, thus in your case, this code will get executed:
var x = 3;
(function (){
var x;
console.log('before', x);
x = 7;
console.log('after', x);
return ;
})();
So your local variable x gets declared at first with an initial value of undefined.
This should explain, why you get an "beforeundefined" for the first console.log().
The scope of a variable is much simpler than in other languages. It doesn't start at declaration but is either :
the function in which you have the declaration
the global scope if the declaration isn't in a function
MDN :
The scope of a variable declared with var is the enclosing function
or, for variables declared outside a function, the global scope (which
is bound to the global object).
You can imagine that all variable declarations are moved to the start of the scope (the function). So this is exactly like
var x = 3;
(function (){
var x;
console.log('before', x); // now undefined
x = 7;
console.log('after', x); // now 7
return ;
})();
Be careful to understand what is the exact scope (the function, not the block) :
var x = 3;
(function (){
console.log('before', x); // this is undefined !
if (true) {
var x = 7;
}
return ;
})();

Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?

JavaScript has lexical scoping which means that non-local variables accessed from within a function are resolved to variables present in the parents' scope of that function when it was defined. This is in contrast to dynamic scoping in which non-local variables accessed from within a function are resolved to variables present in the calling scope of that function when it is called.
x=1
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f # does this print 1, or 3?
echo $x # does this print 1, or 2?
The above program prints 1 and then 2 in a lexically scoped language, and it prints 3 and then 1 in a dynamically scoped language. Since JavaScript is lexically scoped it will print 1 and then 2 as demonstrated below:
var print = x => console.log(x);
var x = 1;
function g() {
print(x);
x = 2;
}
function f() {
var x = 3;
g();
}
f(); // prints 1
print(x); // prints 2
Although JavaScript doesn't support dynamic scoping we can implement it using eval as follows:
var print = x => console.log(x);
var x = 1;
function g() {
print(x);
x = 2;
}
function f() {
// create a new local copy of `g` bound to the current scope
// explicitly assign it to a variable since functions can be unnamed
// place this code in the beginning of the function - manual hoisting
var g_ = eval("(" + String(g) + ")");
var x = 3;
g_();
}
f(); // prints 3
print(x); // prints 1
I would like to know if there exists another possible way to achieve the same result without resorting to eval.
Edit: This is what I'm trying to implement without using eval:
var print = x => console.log(x);
function Class(clazz) {
return function () {
var constructor;
var Constructor = eval("(" + String(clazz) + ")");
Constructor.apply(this, arguments);
constructor.apply(this, arguments);
};
}
var Rectangle = new Class(function () {
var width, height;
constructor = function (w, h) {
width = w;
height = h;
};
this.area = function () {
return width * height;
};
});
var rectangle = new Rectangle(2, 3);
print(rectangle.area());
I know that it's not a very good example but the general idea is to use dynamic scoping to create closures. I think this pattern has a lot of potential.
To add a note on this topic:
In JavaScript whenever you make use of:
function declaration statement or function definition expression then local variables will have Lexical Scoping.
Function constructor then local variables will refer to the global scope (top-level code)
this is the only built-in object in JavaScript that has a dynamic
scoping and is set through the execution (or invocation) context.
So to answer to your question, In JS the this is already dynamically scoped feature of the language and you even don't need to emulate another one.
Attribute lookup falls through the prototype chain, which matches quite well to dynamic scopes. Just pass your own environment of dynamically-scoped variables to use around instead of using Javascript's lexical scoping.
// Polyfill for older browsers. Newer ones already have Object.create.
if (!Object.create) {
// You don't need to understand this, but
Object.create = function(proto) {
// this constructor does nothing,
function cons() {}
// and we assign it a prototype,
cons.prototype = proto;
// so that the new object has the given proto without any side-effects.
return new cons();
};
}
// Define a new class
function dyn() {}
// with a method which returns a copy-on-write clone of the object.
dyn.prototype.cow = function() {
// An empty object is created with this object as its prototype. Javascript
// will follow the prototype chain to read an attribute, but set new values
// on the new object.
return Object.create(this);
}
// Given an environment, read x then write to it.
function g(env) {
console.log(env.x);
env.x = 2;
}
// Given an environment, write x then call f with a clone.
function f(env) {
env.x = 3;
g(env.cow());
}
// Create a new environment.
var env = new dyn();
// env -> {__proto__: dyn.prototype}
// Set a value in it.
env.x = 1;
// env -> {x: 1} // Still has dyn.prototype, but it's long so I'll leave it out.
f(env.cow());
// f():
// env -> {__proto__: {x: 1}} // Called with env = caller's env.cow()
// > env.x = 3
// env -> {x: 3, __proto__: {x: 1}} // New value is set in current object
// g():
// env -> {__proto__: {x: 3, __proto__: {x: 1}}} // caller's env.cow()
// env.x -> 3 // attribute lookup follows chain of prototypes
// > env.x = 2
// env -> {x: 2, __proto__: {x: 3, __proto__: {x: 1}}}
console.log(env.x);
// env -> {x: 1} // still unchanged!
// env.x -> 1
I don't think so.
That is not how the language works. You have to use something other than variables to refer to this state information. The most "natural" way being to use properties of this, I guess.
In your case, instead of trying to use dynamic scoping to set the constructor, what if you used the return value?
function Class(clazz) {
return function () {
clazz.apply(this, arguments).apply(this, arguments);
};
}
var Rectangle = new Class(function () {
var width, height;
this.area = function () {
return width * height;
};
// Constructor
return function (w, h) {
width = w;
height = h;
};
});
var rectangle = new Rectangle(2, 3);
console.log(rectangle.area());
Why didn't anybody say this?
You can pass variables from the calling scope into the called function by binding it a context.
function called_function () {
console.log(`My env ${this} my args ${arguments}`, this, arguments);
console.log(`JS Dynamic ? ${this.jsDynamic}`);
}
function calling_function () {
const env = Object.create(null);
env.jsDynamic = 'really?';
...
// no environment
called_function( 'hey', 50 );
// passed in environment
called_function.bind( env )( 'hey', 50 );
Perhaps it's worth mentioning that in strict mode, all functions have no "environment" sent to them by default (this is null). In non strict mode the global object is the default this value for a called function.
You can simulate dynamic scoping using global variables, if you have a way to do syntactic sugar (e.g. macros with gensyms) and if you have unwind-protect.
The macro can appear to rebind the dynamic variable by saving its value in a hidden lexical and then assigning a new value. The unwind-protect code ensures that no matter how that block terminates, the original value of the global will be restored.
Lisp pseudocode:
(let ((#:hidden-local dynamic-var))
(unwind-protect
(progn (setf dynamic-var new-value)
body of code ...)
(set dynamic-var #:hidden-local)))
Of course, this is not a thread-safe way of doing dynamic scope, but if you aren't doing threading, it will do! We would hide it behind a macro like:
(dlet ((dynamic-var new-value))
body of code ...)
So if you have unwind-protect in Javascript, and a macro preprocessor to generate some syntactic sugar (so you're not manually open-coding all your saves and unwind-protected restores) it might be doable.
I know this doesn't exactly answer the question but it's too much code to put into a comment.
As an alternative approach, you may want to look into ExtJS's extend function. This is how it works:
var Rectangle = Ext.extend(Object, {
constructor: function (w, h) {
var width = w, height = h;
this.area = function () {
return width * height;
};
}
});
With public properties instead of private variables:
var Rectangle = Ext.extend(Object, {
width: 0,
height: 0,
constructor: function (w, h) {
this.width = w;
this.height = h;
},
area: function () {
return this.width * this.height;
}
});

The difference between the two functions? ("function x" vs "var x = function") [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
What's the difference between:
function sum(x, y) {
return x+y;
}
// and
var sum = function (x, y) {
return x+y;
}
Why is one used over the other?
The first is known as a named function where the second is known as an anonymous function.
The key practical difference is in when you can use the sum function. For example:-
var z = sum(2, 3);
function sum(x, y) {
return x+y;
}
z is assigned 5 whereas this:-
var z = sum(2, 3);
var sum = function(x, y) {
return x+y;
}
Will fail since at the time the first line has executed the variable sum has not yet been assigned the function.
Named functions are parsed and assigned to their names before execution begins which is why a named function can be utilized in code that precedes its definition.
Variables assigned a function by code can clearly only be used as function once execution has proceeded past the assignment.
The first tends to be used for a few reasons:
The name "sum" shows up in the
stacktrace which makes debugging
easier in many browsers.
The name
"sum" can be used inside the
function body which makes it easier
to use for recursive functions.
function declarations are "hoisted"
in javascript, so in the first case,
the function is guaranteed to be
defined exactly once.
Semicolon insertion causes
var f = function (x) { return 4; }
(f)
to assign 4 to f.
There are a few caveats to keep in mind though.
Do not do
var sum = function sum(x, y) { ... };
on IE 6 since it will result in two function objects being created. Especially confusing if you do
var sum = function mySym(x, y) { ... };
According to the standard,
function sum(x, y) { ... }
cannot appear inside an if block or a loop body, so different interpreters will treat
if (0) {
function foo() { return 1; }
} else {
function foo() { return 2; }
}
return foo();
differently.
In this case, you should do
var foo;
if (0) {
foo = function () { return 1; }
} ...
The first one is a named function statement, the second one assigns an anonymous function expression to a variable.
The function statement is added to its scope immediately - you don't need to run it before being able to call it, so this works:
var y = sum(1, 2);
function sum(x, y) {
return x + y;
}
But the function expression is only assigned to the variable when the code is executed, so this doesn't work:
// Error here because the function hasn't been assigned to sum yet.
var y = sum(1, 2);
var sum = function(x, y) {
return x + y;
}
An advantage of the expression form is that you can use it to assign different functions to the expression at different points - so you can change the function, or use a different one under different conditions (such as depending on the browser being used).
An advantage of a named function statement, is that debuggers will be able to display the name. Although, you can name function expressions:
var sum = function sum(x, y) {
return x + y;
}
But this can be confusing since the two names are actually in different scopes and refer to different things.
The two code snippets you've posted there will, for almost all purposes, behave the same way.
However, the difference in behaviour is that with the second variant, that function can only be called after that point in the code.
With the first variant, the function is available to code that runs above where the function is declared.
This is because with the second variant, the function is assigned to the variable foo at run time. In the first, the function is assigned to that identifier foo at parse time.
More technical info
Javascript has three ways of defining functions.
Your first example is a function declaration. This uses the "function" statement to create a function. The function is made available at parse time and can be called anywhere in that scope. You can still store it in a variable or object property later.
Your second snippet shows a function expression. This involves using the "function" operator to create a function - the result of that operator can be stored in any variable or object property. The function expression is powerful that way. The function expression is often called an "anonymous function" because it does not have to have a name,
The third way of defining a function is the "Function()" constructor, which is not shown in your original post. It's not recommended to use this as it works the same way as eval(), which has its problems.
The difference is...
This is a nameless function
var sum = function (x, y) {
return x+y;
}
So if you alert(sum); you get "function (x, y) { return x + y; }" (nameless)
While this is a named function:
function sum(x, y) {
return x+y;
}
If you alert(sum); now you get "function sum(x, y) { return x + y; }" (name is sum)
Having named functions help if you are using a profiler because the profiler can tell you function sum's execution time...etcetera instead of an unknown functions's execution time...etcetera
here's an other example:
function sayHello(name) { alert('hello' + name) }
now,suppose you want modify onclick event of a button, such as it says "hello world"
you can not write:
yourBtn.onclik = sayHello('world'), because you must provide a function reference.
then you can use second form:
yourBtn.onclick = function() { sayHello('workld'); }
Ps: sorry for my bad english!
They mean the exact same thing. It's just syntactic sugar. The latter is IMO more revealing of what JavaScript is really doing; i.e. "sum" is just a variable, initialised with a function object, which can then be replaced by something else:
$ js
js> function sum(x,y) { return x+y; }
js> sum(1,2);
3
js> sum=3
3
js> sum(1,2);
typein:4: TypeError: sum is not a function
js> sum
3

Categories

Resources