I have this code when i run it displays undefined. However we can access global property with this keyword.
var firstName = "Peter",
lastName = "Ally";
function showFullName () {
// "this" inside this function will have the value of the window object
// because the showFullName () function is defined in the global scope, just like the firstName and lastName
alert (this.firstName + " " + this.lastName);
}
showFullName ();
This works if executed properly (replaced alert with console.log for easier examples)
var firstName = "Peter",
lastName = "Ally";
function showFullName () {
// "this" inside this function will have the value of the window object
console.log("this and window are the same thing", this === window);
// because the showFullName () function is defined in the global scope, just like the firstName and lastName
console.log(this.firstName + " " + this.lastName);
}
showFullName();
If this is placed in functional scope it will not work, however - presumably JS Fiddle does something like that
(function() {
var firstName = "Peter",
lastName = "Ally";
function showFullName () {
// "this" inside this function will still have the value of the window object
console.log("this and window are the same thing", this === window);
// however firstName and lastName are not goint to be attached to it because they are in functional scope
console.log("the names are still reachable", firstName, lastName)
//but not attached to the window object (which "this" points to)
console.log(this.firstName + " " + this.lastName);
}
showFullName();
})();
Do note that with if you have strict mode enabled then this will be undefined instead of window and the code will produce an error
var firstName = "Peter",
lastName = "Ally";
function showFullName () {
"use strict";
// "this" inside this function will now have the value "undefined"
console.log("'this' is actually 'undefined'", this);
console.log("the actual value 'undefined', not a string", typeof this);
// the following line will throw a TypeError because it's trying to get a property from "undefined"
console.log(this.firstName + " " + this.lastName);
}
showFullName();
Normaly use window keyword instead. this is independent on place where was funciton declared but is dependent on place where was (and how) called.
var firstName = "Peter",
lastName = "Ally";
function showFullName () {
alert (window.firstName + " " + window.lastName);
}
showFullName();
So i came to know that, when we use strict mode, this keyword holds the value of undefined in global functions.
In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined:
function f2(){
"use strict"; // see strict mode
return this;
}
f2() === undefined;
So, in strict mode, if this was not defined by the execution context, it remains undefined.I have taken this code snippet from MDN.
So in my case value is not appearing in fiddle.But it would be reason which is pointed out by #vlaz. Thanks #vlaz
Related
When I define a function as following I'm able to retrieve the name of the function and no of parameters.
let func = function(arg1, arg2){
console.log("I am a function");
}
console.log("Function name : " + func.name);
console.log("No of parameters : " + func.length);
But if I use another function to retrieve a anonymous function in a variable then the function name is displayed as empty string.
let func = function(){
return function(arg1, arg2, arg3){
console.log("Nested anonymous function");
};
}
let func1 = func();
console.log("Function name : " + func1.name); // "func1" expected
console.log("No of parameters : " + func1.length);
So my doubt is in both the cases anonymous functions are getting assigned to some variable. But in first case it abopts variable's name as function's name. But in second case it doesn't. What is the reason of this peculiar behaviour?
Variables and methods can infer the name of an anonymous function from
its syntactic position (new in ECMAScript 2015).
let f = function() {};
let object = {
someMethod: function() {}
};
console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Inferred_function_names
Note the highlight: a name can be inferred from its syntactic position. Meaning, if the function appears in the source code with a left-hand side expression that lets the engine infer a name, it will do so. However, in your case the left-hand side is return, which does not allow to infer any name. Javascript will not track it through being returned from the function and assigned somewhere in the caller, so your anonymous function remains anonymous.
Here's an experiment that supplements your theory. if you name the function being returned by func, func1.name is set to that name. I think it's safe to conclude that function names are only set when initialising the function with the function ...() { ... } syntax
let func = function(){
return function func1(arg1, arg2, arg3){
console.log("Nested anonymous function");
};
}
let func1 = func();
console.log("Function name : " + func1.name); // "func1" set
console.log("No of parameters : " + func1.length);
This question already has answers here:
Why is "this" in an anonymous function undefined when using strict?
(3 answers)
Closed 4 years ago.
I have found weird thing with this JavaScript code.
class Person {
constructor(name) {
this.name = name;
}
speakName() {
console.log(this.name);
}
}
var person = new Person("John");
person.speakName(); // John
var speakName = person.speakName;
speakName(); // Error
I made a object named person from Person class. Invoking internal methods directly works fine, however when I reassign the speakName to global variable var speakName, it gives me this exception:
Cannot read property 'name' of undefined
So I thought that this of reassigned var speakName refers global object(global in Node.js, window in Browser JavaScript), however it wasn't both.
class Person {
constructor(name) {
this.name = name;
}
speakName() {
// console.log(this.name);
if(typeof global !== "undefined") {
console.log(this == global); // false
}
if(typeof window !== "undefined") {
console.log(this == window); // false
}
}
}
So, what exactly "this" points to? I thought that it was global object, but it seems it's not. Could anyone can explain this?
From MDN: The body of a class is executed in strict mode
This means that the value of this is not automatically assigned to the global object when unset and it's instead simply left as undefined. This is the exact error you'd see when running this code
class Person {
constructor(name) {
this.name = name;
}
speakName() {
console.log(this.name);
}
}
var person = new Person("John");
person.speakName(); // John
var speakName = person.speakName;
speakName(); // Error - this is undefined
Compare this with the following example:
var person = {
fullName: "Fred Flintstone", //changed from "name" to avoid collision with the global name property
speakName: function() { //this function is in the default "loose" mode
console.log("My name is: " + this.fullName);
}
}
var strictPerson = {
fullName: "Barney Rubble",
speakName: function() {
"use strict"; // <-- electing to use strict mode for this function
console.log("My name is: " + this.fullName);
}
}
person.speakName(); // <-- "this" refers to "person"
var speakName = person.speakName;
speakName();// <-- "this" refers to the global object
strictPerson.speakName(); // <-- "this" refers to "strictPerson"
var speakNameStrict = strictPerson.speakName;
speakNameStrict();// <-- "this" is undefined
As you can see, in the default mode of execution this is indeed reassigned but with strict mode on you would get the same result as when using a class.
I wrote the following code, where I would expect the calls to getFull() and useGetFull() to do the same thing, since useGetFull just gets a function object for getFull() and calls it.
function Person(name, family) {
this.name = name;
this.family = family;
}
Person.prototype.getFull = function() {
console.log(this.name + " " + this.family);
};
Person.prototype.useGetFull = function() {
const f = this.getFull;
f();
// f.call(this) works as expected
}
p = new Person("Bob", "Smith");
p.getFull();
p.useGetFull();
However, they don't do the same thing, because inside useGetFull(), "this" is the global object. I noticed that using f.call(this) instead of f() works as intended, but I can't wrap my head around why I have to use it. Why is the value of "this" different depending on how/where I call the function?
A simple rule:
a.b() //b called with context a
d.e() //e called with context d
c() // c called with no context ( so the global instead)
Javascripts context depends on how the function was called.
If you haven't noticed, this.getFull() also works. This is because when you invoke the function as a property of an object (any object), that function's this will refer to that object, the object you invoked the function on, in case of foo.bar(), foo, and in case of this.getFull(), this. This is why this example works as expected:
function Person(name, family) {
this.name = name;
this.family = family;
}
Person.prototype.getFull = function() {
console.log(this.name + " " + this.family);
};
Person.prototype.useGetFull = function() {
/* getFull is preceded by something, it is invoked through "this", so
the "this" reference inside of getFull will be set to the "this" part in
the statement "this.getFull()". */
this.getFull();
}
p = new Person("Bob", "Smith");
p.getFull(); prints out Bob Smith
p.useGetFull(); // prints out Bob Smith
However, when a function is invoked not as the property on an object, in other words, when it is not accessed in a way similar to either foo.bar() or foo["bar"](), but in a way like foo(), even if foo is a reference to a variable whose value is x.y, like f() in your example, its this will be bound to the global object, in a browser, that object is window.
function Person(name, family) {
this.name = name;
this.family = family;
}
Person.prototype.getFull = function() {
console.log(this.name + " " + this.family);
};
Person.prototype.useGetFull = function() {
const f = this.getFull;
/* this call is not preceded by any objects, it is a plain
traditional function call, it is a function invokation in its
simplest form. all functions invoked in this manner will have
their "this" reference set to the global object. */
f();
}
p = new Person("Bob", "Smith");
p.getFull();
p.useGetFull();
If you are interested in this (pun not intended), go here.
I'm somewhat new to JavaScript and have a few questions about scope that don't seem to have been explicitly asked about before. At the top of a function I'm working on in angular a variable vm is set equal to this. I understand that anything prefaced with vm going forward will be in scope of this however how is this different from being in the function's scope to begin with? To be more explicit, how would vm.foo = "test" differ from var foo = "test" inside of a function in terms of its scope. Any help would be much appreciated.
If you set vm = this, then properties of vm can persist beyond the scope of the current function invocation. In contrast, a local variable value (e.g., var foo = "test") does not persist past the current function invocation.
Basically, this.foo within a function is not equivalent to var foo within that same function. The first actually references a property value on the this object, whereas the second only references a local variable in the current function invocation scope.
Here's an example to illustrate this difference:
function myFunction(myArg) {
console.log("this.foo = " + this.foo);
console.log("foo = " + foo);
var foo = "test";
console.log("foo' = " + foo);
var vm = this;
console.log("vm.foo = " + this.foo);
vm.foo = myArg;
console.log("vm.foo' = " + this.foo);
}
console.log("window.foo = " + window.foo);
console.log(">>> Test call 1");
myFunction("abc");
console.log("window.foo = " + window.foo);
console.log(">>> Test call 2");
myFunction("xyz");
console.log("window.foo = " + window.foo);
For convenience, here is the console output:
window.foo = undefined
>>> Test call 1
this.foo = undefined
foo = undefined
foo' = test
vm.foo = undefined
vm.foo' = abc
window.foo = abc
>>> Test call 2
this.foo = abc
foo = undefined
foo' = test
vm.foo = abc
vm.foo' = xyz
window.foo = xyz
As you can see, this inside the function actually refers to the global window object. That means that the value of vm.foo that you assign inside the function is actually available anywhere that window is accessible (i.e., everywhere in your script). You can change what object is used as this if you invoke the function using its call method, and explicitly pass a different object as thisArg. You can also get a different object as this if you invoke the function as a method on some object. Here's an example illustrating both of these possibilities:
function myFunction(myArg) {
console.log("this.foo = " + this.foo);
console.log("foo = " + foo);
var foo = "test";
console.log("foo' = " + foo);
var vm = this;
console.log("vm.foo = " + this.foo);
vm.foo = myArg;
console.log("vm.foo' = " + this.foo);
}
var x = { f: myFunction };
var y = { f: myFunction, foo: "YYY" };
var z = { foo: "ZZZ" };
x.f("x"); // "this" is "x"
y.f("y"); // "this" is "y"
myFunction.call(z, "z"); // "this" is "z"
console.log("x.foo = " + x.foo);
console.log("y.foo = " + y.foo);
console.log("z.foo = " + z.foo);
Notice how the calls that use y and z for this have initial values of this.foo, since the corresponding objects are initialized with a value for the foo property. The value of this.foo persists in the object referenced by this, not in the function itself (unless of course this is referencing the function itself).
Inside a function, var foo = 'test' does not necessarily relate foo to this, because the value of this depends on how the function was called (see Function context).
Rather independently of the above, the reason for assigning this to vm is to keep its reference in case you want to have another function inside this function, where you refer to the original context of this. This is usually done within a controller function, see this Angular Style Guide.
I have read through call() method and wondering on the global output below. Shouldnt it be this.name where in this case "Michael". However the output displayed is undefined.
---NEW INFORMATION : THIS IS RUNNING THROUGH NODEJS---
function sayNameForAll(label) {
console.log(label + ":" + this.name);
}
var person1 = {
name: "Nicholas"
};
var person2 = {
name: "Greg"
};
var name = "Michael";
sayNameForAll.call(this,"global"); //ouput global:undefined
sayNameForAll.call(person1,"PersonName1"); //PersonName1:Nicholas
sayNameForAll.call(person2,"PersonName2"); //PersonName2:Greg
The reason is probably that in this context, this is not the same scope. This can happen because of several reasons:
You're running this in a function (even a (function() { self invoking function })())
You're running this in nodejs and not in the browser, in node, in the global scope, this is undefined as opposed to window in the browser.
Works fine here (click Run Snippet).
Is your code running inside another function? If it is, then the variables you declare would not be on the global object and depending on how you are invoking the function, this might not refer to the global object.
function sayNameForAll(label) {
console.log(label + ":" + this.name);
}
var person1 = {
name: "Nicholas"
};
var person2 = {
name: "Greg"
};
var name = "Michael";
sayNameForAll.call(this,"global"); //ouput global:undefined
sayNameForAll.call(person1,"PersonName1"); //PersonName1:Nicholas
sayNameForAll.call(person2,"PersonName2"); //PersonName2:Greg