In my understanding, it is not until an object invokes a Function that this is actually assigned a value. And the value it is assigned is based exclusively on the object that invokes the Function.
Also, the scope chain rule in JS is LEG.
So, in (strict mode):
function one () {
var a = 2;
function two () {
console.log(a)};
two()
}
one() // output 2
But:
function one () {
var a = 2;
function two () {
console.log(this.a)};
two()
}
one() //output undefined
It was my understandig functions were objects, and in the previous invokation the function object one would be the making the call of two, which translates this.a into one.a. Obviously that is not the case.
Also:
function one () {
var a = 2}
console.log(one.a) //outputs undefined
Any clarification about what is happening would be very appreciated.
Thanks
function one () {
var a = 2;
function two () {
console.log(this.a)};
two()
}
one() //output undefined
Here you are calling both one and two as functions on their own, not as properties of some object (e.g. someObject.one()). This means that this will refer to the global scope (or to undefined if the code is in strict mode). The a property of your global scope is undefined, so that's why you see undefined. Calling two() inside of one() doesn't make it so that this refers to one.
function one () {
var a = 2}
console.log(one.a) //outputs undefined
a is not a property of one. It is a variable inside it. A property of one would look like this.
function one() {
}
one.a = 7;
console.log(one.a);
I think you are treating a regular function as a class object. You only call one() but you do not actually instantiate a new One() object.
Scope and Context are different concepts. Within a JS-Function scope one can address any value that either got assigned inside a function or any value that got assigned outside such a function as long as this function itself is a member of the outer scope. In addition, as long as a function does not create a closure, scope gets created just at a function's call time. Context is addressable too. But unlike scope, context gets evaluated at a functions call time. Thus this is just a placeholder for context that can vary from one time calling a function to another.
function contextAwareMethod(injectedValue) {
"use strict";
var
context = this, // dynamically evaluated.
innerScopeValue = "created at a functions call time";
console.log('dynamically evaluated context : ', context);
console.log('this.contextValue : ', (context && context.value));
console.log('innerScopeValue : ', innerScopeValue);
console.log('injectedValue : ', injectedValue);
}
console.log('"case A"');
contextAwareMethod('argument A');
console.log('\n');
console.log('"case B"');
contextAwareMethod.call({ value: "conext B"});
console.log('\n');
console.log('"case C"');
contextAwareMethod.call({ value: "conext C"}, 'argument C');
console.log('\n');
.as-console-wrapper { max-height: 100%!important; top: 0; }
Related
1 style
var x = function(xx) {
}
another
x : function (xx) {
}
what's the difference between those two styles
In the first case, the result of evaluating a function expression (i.e. the resulting function — evaluation is not calling) is assigned to a variable.
In the second case, you start with a label and then have a syntax error.
You probably meant:
var foo = {
x : function (xx) {
}
}
… which is an object literal where the function is assigned to a property of the new object instead of a variable.
The first is an assignment of an anonymous function into a variable x.
The seconds isn’t valid JavaScript at all, at least how you are showing it.
If this is inside an object, like this:
var dog = {
x : function (xx) {
}
};
It is simply an property containing an anonymous function.
The first is assigning a local variable to a function definition
The second is using object notation to assign a function to a object member.
i.e.
var obj = {
x : function (y) { }
};
In the 1st case we are binding the function to javascript variable which is in the global scope. So in 1st case that function gets bound to the 'x' key in windows object.
Where as in second case that function gets bound to the object in which you are planning to add 'x' key.
Can anyone explain why
function x() {
console.log("Hello!");
}
var a = x;
a();
x();
produces
Hello!
Hello!
but this
var a = function x() {
console.log("Hello!");
}
a();
x();
throws an error when you try to call function x? Is the second x function not considered a hoisted function? I tried this in both nodejs and a browser.
What you have in the second example is what's called a named function expression.
Its name is not added to the containing scope, but is accessible within the scope of the function itself:
var a = function x() {
alert(x);
};
a();
This is useful in writing recursive functions or functions that otherwise reference themselves, as it ensures that the name won't get clobbered due to anything that happens outside the function's scope.
It also allows you to create self-referencing functions in places where you can't use a function declaration, such as in an object literal:
var myFavoriteFunctions = {
factorial: function f(n) {
return n === 1 ? 1 : n * f(n);
},
identity: function (v) { return v; }
};
console.log(myFavoriteFunctions.factorial(10));
Your first example is a function statement, which declares a name in its containing scope.
Your second example is a named function expression, which does not.
For more information, see here.
This code new Function('fn', 'fn()') creates anonymous function which has param and (in this case the param is a function) executed.
Doing console.log(new Function('fn', 'fn()')) shows the output :
function anonymous(fn)
{
fn()
}
Now , the docs states :
Note: Functions created with the Function constructor do not create
closures to their creation contexts; they always are created in the
global scope. When running them, they will only be able to access
their own local variables and global ones, not the ones from the scope
in which the Function constructor was called. This is different from
using eval with code for a function expression.
Ok.
So why does this code yields 1 and not 44 ?
var a = 44;
function myFunc()
{
var a = 1;
function f()
{
alert(a)
}
new Function('fn', 'fn()')(f);
}
myFunc();
Why ?
What about this line above ?
they will only be able to access their own local variables and global
ones, not the ones from the scope in which the Function constructor
was called
It looks like the f is closure over the parent a , but how come ? it suppose to be run at global , and able to access local and global only !
What am I missing ?
Because you're invoking function f, which is a normal function that does create a closure.
The documentation refers to this:
var a = 44;
function myFunc()
{
var a = 1;
new Function('fn', 'alert(a)')(); //shows 44, not 1
}
myFunc();
In your example you call f function that defined inside myFunc function. Does not matter where you called it from. So you called you anonymous function that is defined in global scope and see a = 44, anonymous function called f function that is defined in myFunc scope and see a = 1.
I'm not sure what exactly you want to achieve with this code, but if you need 44 in your f you need to pass it there as an argument.
var a = 44;
function myFunc() {
var a = 1;
function f(myArgument) {
alert(myArgument)
}
new Function('fn', 'fn(a)')(f);
}
myFunc();
I was reading some documentation about javascript and stumbled upon the following code example:
var o = {
value: 1,
outer: function () {
var inner = function () {
console.log(this); //bound to global object
};
inner();
}
};
o.outer();
It outputs window.
I cannot figure out why is the this keyword bound to the global object (window) instead of the parent object (outer).
If you want to access outer from inner's scope, you have to pass the outer's this (which is just like passing outer itself) to its local inner function as an argument. So, as expected:
var o = {
value: 1,
outer: function () {
var inner = function (that) {
console.log(that); //bound to global object
};
inner(this);
}
};
o.outer();
outputs outer.
Isn't it a bit of a nonsense that in outer's scope this is bound to the object itself (i.e. outer), while in the inner's scope, which is local to outer, this is re-bound to the global object (i.e. it overrides outer's binding)?
The ECMAScript specs states that when entering the execution context for function code if the «caller provided thisArg» is either null or undefined, then this is bound to the global object.
But the following:
var o = {
outer: function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
}
outputs the object outer itself:
caller is function () {
var inner = function () {
console.log('caller is ' + arguments.callee.caller);
};
inner();
}
On a side, but probably relevant, note:
In strict mode the first code snippet outputs undefined instead of window.
This is because this is set when the function is run, not when it's defined.
For example:
var o = {
func: function(){
console.log(this);
}
};
When you call o.func(), you are doing so in the context o, so it works as expected.
Now let's say you do this:
var f = o.func;
f();
This will not work as expected. This is because when you call f(), it doesn't have any context attached to it, so this will be window.
You can fix this by using .call to change the value of this.
var f = o.func;
f.call(o); // sets `this` to `o` when calling it
That's just how it the language works.
Every time a function is called, this will be reset. In a nested (inner) function it does not inherit the value from the enclosing scope the way other (explicitly declared) variables are.
By default this will be set to window, unless the function is invoked as:
myObj.func(arg1, ...) or
func.call(myObj, arg1, ...) or
func.apply(myObj, [arg1, ...])
in which case this will be equal to myObj
A function called any other way, even if it was originally defined as a property of an object (i.e. var func = myObj.func; func() will use window.
There's also a utility function called .bind which wraps a function reference in such a way that you can provide a specific value which will always be used as this:
var myFunc = myObj.func; // obtain reference to func
var bound = myFunc.bind(someOtherObj); // bind it to "someOtherObj"
bound(); // this === someOtherObj
bound.call(myObj) // this still === someOtherObj
I got a piece of code for javascript which I just do not understand:
function dmy(d) {
function pad2(n) {
return (n < 10) ? '0' + n : n;
}
return pad2(d.getUTCDate()) + '/' +
pad2(d.getUTCMonth() + 1) + '/' +
d.getUTCFullYear();
}
function outerFunc(base) {
var punc = "!";
//inner function
function returnString(ext) {
return base + ext + punc;
}
return returnString;
}
How can a function be defined within another function? Can we call pad2() from outside of my() function?
Please put some light on it. Thanks
Functions are another type of variable in JavaScript (with some nuances of course). Creating a function within another function changes the scope of the function in the same way it would change the scope of a variable. This is especially important for use with closures to reduce total global namespace pollution.
The functions defined within another function won't be accessible outside the function unless they have been attached to an object that is accessible outside the function:
function foo(doBar)
{
function bar()
{
console.log( 'bar' );
}
function baz()
{
console.log( 'baz' );
}
window.baz = baz;
if ( doBar ) bar();
}
In this example, the baz function will be available for use after the foo function has been run, as it's overridden window.baz. The bar function will not be available to any context other than scopes contained within the foo function.
as a different example:
function Fizz(qux)
{
this.buzz = function(){
console.log( qux );
};
}
The Fizz function is designed as a constructor so that, when run, it assigns a buzz function to the newly created object. That is, you'd use it like this:
const obj = new Fizz();
obj.buzz();
or more concisely (if you don't need to keep the object after calling buzz):
new Fizz().buzz();
It is called closure.
Basically, the function defined within other function is accessible only within this function. But may be passed as a result and then this result may be called.
It is a very powerful feature. You can see more explanation here:
javascript_closures_for_dummies.html mirror on Archive.org
function x() {}
is equivalent (or very similar) to
var x = function() {}
unless I'm mistaken.
So there is nothing funny going on.
Function-instantiation is allowed inside and outside of functions. Inside those functions, just like variables, the nested functions are local and therefore cannot be obtained from the outside scope.
function foo() {
function bar() {
return 1;
}
return bar();
}
foo manipulates bar within itself. bar cannot be touched from the outer scope unless it is defined in the outer scope.
So this will not work:
function foo() {
function bar() {
return 1;
}
}
bar(); // throws error: bar is not defined
When you declare a function within a function, the inner functions are only available in the scope in which they are declared, or in your case, the pad2 can only be called in the dmy scope.
All the variables existing in dmy are visible in pad2, but it doesn't happen the other way around :D
It's perfectly normal in JavaScript (and many languages) to have functions inside functions.
Take the time to learn the language, don't use it on the basis that it's similar to what you already know. I'd suggest watching Douglas Crockford's series of YUI presentations on JavaScript, with special focus on Act III: Function the Ultimate (link to video download, slides, and transcript)
function foo() {
function bar() {
return 1;
}
}
bar();
Will throw an error.
Since bar is defined inside foo, bar will only be accessible inside foo.
To use bar you need to run it inside foo.
function foo() {
function bar() {
return 1;
}
bar();
}
Nested functions can be the basis for writing a modular group of related functions, kind of halfway to full object-oriented programming (static classes only).
Here is an example of such a group of functions, in this case to convert a value to a JSON string or a JSON string to a value.
Notice how the inner functions are grouped into an Object inside an outer function, and how the Object is then stored into a group name. This is the only name directly visible from outside the group. To reach any contained function from outside, you just write the group name, a period, then the function name. To reach a contained function from inside, you can use the same notation, or 'this', a period, then the function name.
//--------------------------------------------------------------------//
// Module J:
// Convert from and to JSON strings
//--------------------------------------------------------------------//
const J=NewJ();
function NewJ()
{
const mod=
{
From:(str)=>
{
return JSON.parse(str);
}, // From
To:(val)=>
{
return JSON.stringify(val,null,3);
} // To
}; // mod
return mod;
} // NewJ
//--------------------------------------------------------------------//
// End Module J
//--------------------------------------------------------------------//
Here's a test:
console.log(J.To({A:'a'}));
Console output:
{
"A": "a"
}