Does a getter with Object.defineProperty have access to the instance? [duplicate] - javascript

This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 5 years ago.
Let's say there is a Person:
const Person = function(fname, lname) {
this.fname = fname;
this.lname = lname;
};
And I want to extend its functionality with a "name" getter
Object.defineProperty(Person.prototype, 'name', {
get: () => `${this.fname} ${this.lname}`
});
However, this does not work. The this in the getter is not the instance prototype on which it is called:
const p = new Person('Taylor', 'Swift');
p.name // "undefined undefined"
Rather it is the scope of the property definition:
fname = 'Someone';
lname = 'Else';
p.name // "Someone Else"

In the process of writing this question, the answer was obvious. Still posting in case it helps someone else.
Getter properties are indeed bound to their host object.
The issue is that I was using an arrow function for the getter. The arrow function does not have its own this, instead using the this value of the enclosing execution context.
This means the binding done for getter properties has no effect.
For example:
const foo = () => this.document;
foo() // global document object
foo.call({document: 'na'}) // still global document object
const bar = foo.bind({document: 'na'});
bar(); // still global document object

Related

accessing function properties from one of its prototypes [duplicate]

This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 2 years ago.
I am sure that I misunderstand how i can access function properties from one of its prototypes .
i may got -10 because of this question , but I truly need help in understanding why it always returns undefined
here is a reference
function lookup() {
if (!(this instanceof lookup)) {
return new lookup();
}
this.url = "/administration/lookups";
};
lookup.prototype.partial_create = () => {
alert(this.url);
};
var lookup1 = function(){
this.url = "/administration/lookups";
}
lookup1.prototype.makealert = ()=>{
alert(this.url);
}
$(()=>{
new lookup().partial_create();
new lookup1().makealert();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
It's because you've defined both the prototype methods as arrow functions - which behave differently from other functions with regard to the this keyword. (This indeed is the main point of using arrow functions in the first place - but they are misplaced here.) In particular (as you can read at the above link), arrow functions use the this of their enclosing scope - which here is the global scope. So this does not refer to your instance of lookup, but to the global object - hence this.url is just the global variable url, which (since you haven't defined such a variable) is undefined.
To show the difference, run the below snippet - which is identical to yours with the arrow functions replaced by "regular" function declarations. This now works as you presumably intend:
function lookup() {
if (!(this instanceof lookup)) {
return new lookup();
}
this.url = "/administration/lookups";
};
lookup.prototype.partial_create = function() {
alert(this.url);
};
var lookup1 = function(){
this.url = "/administration/lookups";
}
lookup1.prototype.makealert = function() {
alert(this.url);
}
$(()=>{
new lookup().partial_create();
new lookup1().makealert();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

javascript: prototype issue with fat arrow function [duplicate]

This question already has answers here:
What does "this" refer to in arrow functions in ES6?
(10 answers)
ES6 arrow functions not working on the prototype?
(4 answers)
Closed 5 years ago.
I am facing some issue or may it something new comes with fat-arrow function while implementing prototype.
Here is the problem::
function baseClass() {
this.name = "Pankaj";
}
baseClass.prototype.fnGetName = function() {
return this.name;
};
baseClass.prototype.fatArrayGetName = () => {
return this.name;
};
var classObject = new baseClass();
Now when I try to retrieve name property of class using methods as:
classObject.name; // returns Pankaj
classObject.fnGetName() // returns Pankaj
classObject.fatArrayGetName() // returns "" (EMPTY STRING)
Just want to know why fatArrayGetName function return empty string where as it should return name property value.

javascript - why is 'this' not referencing the object? code below [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 5 years ago.
I don't understand why this.name isn't the same as obj.name, basically why in this case this refers to the window object and not the obj object. In the code below, this.name is instantiated after obj.name..
function createNewPerson(name) {
var obj = {};
obj.name = name;
alert(this.name);
return obj;
}
Per MDN:
Inside a function, the value of this depends on how the function is
called. Since the following code is not in strict mode, and because
the value of this is not set by the call, this will default to the
global object , which is window in a browser.
So in your case you have this as the Window object, not the obj. You may get the obj context inside your function via binding it manually, for example:
function createNewPerson(name) {
console.log(this.name); // Hello
console.log(name); // World
}
var obj = {};
obj.name = 'Hello';
var salva = createNewPerson.apply(obj, ['World']);
But what you really need, as I can understand, is a function cunstructor and instantiating an object via new operator:
function createNewPerson(name) {
this.name = name;
}
var salva = new createNewPerson('Salva');
console.log(salva.name); // Salva

Visibility of "this" in Arrow Functions [duplicate]

This question already has answers here:
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 6 years ago.
I have two cases
const test = {
foo: function (){
this.bar();
},
bar: function (){
console.log('bar');
}
}
test.foo();
in this case, everything works correctly.
const test = {
foo: () => {
this.bar();
},
bar: () => {
console.log('bar');
}
}
test.foo();
In second case I get error:
Uncaught TypeError: Cannot read property 'bar' of undefined
I know I can wrote test.bar() in foo function, but I'm interested why this not available in arrow functions scope in this case.
Normally, the value of this in a function depends on how that function is called.
Arrow functions import the value of this from the scope in which the function was created.
In the middle of an object literal, the value of this will depend on what is around the object literal, but certainly won't be the object itself.

Why does 'this' refer to the object 'obj' not global object [duplicate]

This question already has answers here:
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 6 years ago.
var obj = {
name: 'hello',
getName: function(){
return () => {return this.name; }
}
}
var name = 'world';
var nameFunc = obj.getName();
console.log(nameFunc())
And the result is "hello",not "world".
I am a little confused.
Arrow functions are "born" bound to the value of this as it was at the time of their creation. When you make your call to getName():
var nameFunc = obj.getName();
then inside getName() the value of this is a reference to obj. Your return statement constructs the arrow function, and that function is therefore bound to obj. It's as if you'd written:
getName: function() {
return function() {
return this.name;
}.bind(this);
}
That's just the way arrow functions work, and yes it's different from regular functions.

Categories