Why the arrow function returned in the following example doesn't prints undefined
let obj = {
a: "88",
c: () => {
console.log(this.a);
},
d: function() {
return () => {
console.log(this.a);
}
}
}
let ob = {
a: 99
}
let t = obj.d()
t(); // its printing 88 not undefined why
d was created with a function expression
Therefore when you call obj.d() the value of this is the same as the value of obj.
d returns an arrow function.
Arrow functions have lexical this so it uses this from d which was the same as obj
this.a is therefore the same as obj.a which is "88"
Because when you do let t = obj.d(), it will return you a function that will be saved in t
t = () => {
console.log(this.a);
}
Now talking about this.a, here this will the obj and value of a in obj is 88 do that is the reason 88 is printed
Related
var obj = {
a: 2,
}
var a = 3;
const func = () => {
console.log(this.a);
}
function test() {
setTimeout(func, 100);
}
function test2() {
setTimeout(() => {
console.log(this.a);
}, 100);
}
test.call(obj); //3
test2.call(obj); //2
It seemed that the test and test2 are the same, but the returned result is different, what's the problem with 'this'?
with test arrow function, this will refer to the window object, and as var a = 3, the a will be assigned as a property to the window, it will be like
window.a
But in test2 this will refer to the obj object.
I am getting an issue in the below code:
let a = 13;
function printA() {
let a = 19;
console.log(this.a);
}
let obj = {
a: 10,
fun: function() {
console.log(this.a);
}
};
let obj2 = {
a: 20
};
let x = obj.fun;
x();
can anybody tell why it is printing undefined ?
It prints 13 when we remove let from let a = 13
There is no a for your x to fetch, that is why you get undefined.
let obj = {
a: 10,
fun: function () {
console.log(this.a);
}
};
let x = obj.fun;
x();
Your x is pointing to a function as obj.fun. But there is no obj.fun.x exist, so it will result undefined.
Try the following:
let obj = {
a: 10,
fun: function () {
console.log(this.a);
}
};
let x = obj;
x.fun();
or
let obj = {
fun: function () {
this.a = 10;
console.log(this.a);
}
};
let x = obj.fun;
x();
They both will result 10 as output.
These two example both have an x property under the x.
NOTE: By making a let a = 10 under the fun function will not give you result of this.a is because such declaration works like a private parameter declaration in C/JAVA etc.
I found this code in a book:
function foo() {
console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2
What does last line mean?
The last line is doing an assignment and then calling the function.
Assignment happens first
(p.foo = o.foo)
Then call the function
(p.foo = o.foo)();
In this second call to foo, it is being called outside of the scope of p or o, so it's essentially the same as calling:
foo();
let o = {
x: 1,
foo() {
setTimeout(()=>
console.log(this.x),
100);
}
}
o.foo();
This prints out 1 after 100ms.
Is this because it is equivalent to the following, meaning that the lexical this binding of arrow functions works?
let o = new (function Object() {
this.x = 1;
this.foo = ()=> console.log(this.x);
});
o.foo();
Is this because it is equivalent to the following, meaning that the lexical this binding of arrow functions works?
No, it's much simpler than that. It's equivalent to
var o = {
x: 1,
foo: function() {
setTimeout(()=>
console.log(this.x),
100);
}
};
o.foo();
and with the arrow function converted:
var o = {
x: 1,
foo: function() {
var self = this;
setTimeout(function() {
console.log(self.x)
}, 100);
}
};
o.foo();
Since you are calling o.foo(), this inside foo refers to o. Because an arrow function's this is subject to lexical scope, it access foo's this.
Will this calc function be defined once (put on the prototype chain for the 'obj' variable)? If not, then how can I get the calc function on the prototype chain so all instantiations of Obj will reference the same calc function?
I tried assigning the calc function to Obj.prototype.calc, but then when 'obj' is created, it can't find it in the creation process.
window.onload = function () {
var Obj = function (obj) {
var calc = function (o) {
for (p in o) {
if (o.hasOwnProperty(p) && typeof o[p] === 'function') {
o[p] = o[p]();
}
}
return o;
};
return calc(obj);
};
function test() {
var obj = new Obj({
a: 1,
b: 2,
c: function () {
return this.a + this.b;
},
d: function () {
return this.b * this.c;
}
});
window.console.log(obj.a); // 1
window.console.log(obj.b); // 2
window.console.log(obj.c); // 3
window.console.log(obj.d); // 6
}
test();
}
The purpose of the Obj constructor is creating an object literal type syntax when I define many versions of 'obj' but allowing the use of the 'this' keyword to calculate properties in terms of other properties in each object.
Here is the version with the prototype definition which doesn't work:
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {
var Obj = function (obj) {
return calc(obj);
};
Obj.prototype.calc = function (o) {
for (p in o) {
if (o.hasOwnProperty(p) && typeof o[p] === 'function') {
o[p] = o[p]();
}
}
return o;
};
function test() {
var obj = new Obj({
a: 1,
b: 2,
c: function () {return this.a + this.b;},
d: function () {return this.b * this.c;}
});
window.console.log(obj.a);
window.console.log(obj.b);
window.console.log(obj.c);
window.console.log(obj.d);
}
test();
}
</script>
</head>
<body>
</body>
</html>
Will this calc function be defined once (put on the prototype chain for the 'obj' variable)?
No, it gets re-created every time your Obj function is called. (Also note that as Pointy, er, pointed out, you're falling prey to The Horror of Implicit Globals with your calc symbol.)
If not, then how can I get the calc function on the prototype chain so all instantiations of Obj will reference the same calc function?
By putting it there, and then using it from there:
Obj.prototype.calc = /* ...the function, use `this` rather than an argument... */;
and in Obj:
this.calc(); // No `return` needed
Simplified example:
var Foo = function(x, y) {
this.x = x;
this.y = y;
this.calc();
};
Foo.prototype.calc = function() {
this.z = this.x + this.y;
};
var f = new Foo(2, 3);
console.log(f.z); // "5"