Why call function in window scope is different from object scope [duplicate] - javascript

This question already has answers here:
Using the variable "name" doesn't work with a JS object
(4 answers)
Closed 5 years ago.
Why calling Person in window scope is returning "[Object Object]" while call that in object scope is returning Object.

global window object already have a property of name, and it's inside the scope of native code.
https://www.w3schools.com/jsref/prop_win_name.asp

window.name is a getter/setter to set the name of the window. As such, it has to be of type string.
Try this:
window.name = ["something", "else"];
You will see that now window.name is set to "something,else"; which is the result of Array.toString().
This is exactly what is happening here. When you call an object's toString, you get [object Object].
Your program works fine if you do not use the predefined window.name getter/setter.
function Person(first, last) {
this.something = {
first,
last
};
}
f = {};
Person.call(f, "fsd", "fsd");
console.log(f.something);
g = window;
Person.call(g, "fsd", "fsd");
console.log(g.something);
More on getter/setters in javascript:
Setters: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/set
Getters: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/get

Related

Why can't I access properties directly within this object? [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 3 years ago.
I have read the documentation for https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
Why can't we directly access this.prop, but rather we have to write a function just to return this.prop?
var test = {
prop: 42,
func: function() {
return this.prop;
},
directAccess: this.prop
};
console.log(test.func());
// expected output: 42
console.log(test.directAccess);
// expected output: 42
// actual output: undefined
It's all about context, at the time you're constructing the object test , the this context is the parent scope which is creating the object.
When invoking the function, your scope is now that of test which at that point does have a property of prop.
You can directly access prop. However, the way to do that is to use test.prop.
In JavaScript, this is a special variable that is set to the "receiver" of a function call, meaning the object to the left of the dot. When you write
test.func()
then test is the receiver, so this points to test inside the function.
In the case of directAccess, there is no function. The expression this.prop is evaluated at the time test is defined. At this point, this is probably the JavaScript default object, which does not have a property called prop, so you get undefined.
You might be used to Java, in which this inside a class always refers to an instance of the class itself. It doesn't work that way in JavaScript.

Why do I need to bind a shadowed function that is called through the same object? [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 4 years ago.
Was doing some dirty things to Array.prototype when I ran into this:
Array.prototype.hook_pop = function(callback) {
var base_pop = this.pop.bind(this); //<-- this works
var base_pop = this.pop; //<-- this doesn't work
this.pop = function() {
var ret = base_pop();
callback(ret, this);
return ret;
}
}
Initially I tried using the non-working option and got an error "Uncaught TypeError: Cannot convert undefined or null to object".
The way I've understood it, unless otherwise bound, "this" should point to the object through which the method is called from, in this case the array instance. When called on the same object though, either way, "this" should be the same when being passed to the pop function, whether its bound or not. Why doesn't the second option work?
var ret = base_pop();
In this line you're invoking base_pop() by itself, and not as a method of any object. Because of this, its this value isn't set.

Why "this" is not working? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
In java script when we make a new constructor function we use "this.property name". We use "this" to refer the object which currently in use. But in a general function we doesn't use "this" keyword. According to my understanding if we use "this" in function it should point to the current function. However when we used, it was not producing the expected result. Why? Example
function greet(name){ console.log("Hello " + this.name);
}
Output is "Hello" then blank.
Because in general function, we are by default referring 'window' object so anything we make it becomes window level object or variable.
Like,
function fun(){
this.title = "window";
}
fun();
or window.fun(); //both are same. Since we call window.fun, this.title means window.fun.
If you create like this:
var obj = {
}
**Now to make title at obj level, you can do like this:
fun.call(obj);
Now you can call obj.title.**
Read this about this
In most cases, the value of this is determined by how a function is called.
When you use the new keyword in javascript an implicit object is created and returned from the function call. Inside of the function this refers to the newly created object. Calling a function without new does not have the same behavior.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

Why does passing a JavaScript object's method not update the object? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
I noticed that when passing an object's method (which updates one of the object's own properties) as an argument to another function, the original object will not be modified.
For example:
var obj = {
foo: 0,
bar: function () {
this.foo++;
}
};
function baz(callback) {
callback();
}
baz(obj.bar); // does not alter obj
obj.bar(); // increments obj.foo successfully
console.log(obj.foo); // should be 2, not 1
Why is this, since JavaScript objects are passed by reference?
This is because the context - or this value - of a function is based on how it's called, not on how it's defined. Your bar function doesn't know it's inside the obj object.
When you do obj.bar();, you are calling it in the context of obj, thus this is what you expect.
When you do baz(obj.bar);, you are passing the bar function as a parameter. It no longer has any ties to the obj object. Remember, functions can be treated like variables. So, when baz runs its callback, it's ran in the "global" context (this is window).
The solution here is to use .bind() to "lock in" the this value.
baz(obj.bar.bind(obj));
Because you need to bind the callback to a specific object.
baz(obj.bar.bind(obj));
Functions are only automatically bound to the object before . when you perform the call in the same expression. Simply accessing the property doesn't bind it.

Access Object AND property of object using variables in Javascript [duplicate]

This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 7 years ago.
I am aware you can access properties of objects in javascript using variables like this Object['property'] but I want to access the Object using a variable too.
// The object and his function
var Foo = {};
Foo.bar = function() { console.log("I am a useful function dood"); }
// The accessors
var obj = 'Foo';
var method = 'bar';
But when I try it in the way I think is right, I get the following. As all links in the world seem to be about accessing object properties with variables I don't seem to be able to sift one out that accesses objects like this too.
typeof obj // "object"
typeof Foo[method] // "function"
typeof [obj].foo // undefined
typeof [obj][method] // undefined <-- This is what I'm trying to use
Am I able to access the object like this?
EDIT
According to answers, if the object is globally scoped I could use window[obj][method] but the above is contained in an immediately invoked function like this:
(function(){
// The stuff from above...
})();
Will this work I will have to put this into an identifiable var that is globally scoped?
PS I will never ever use eval();
If your Foo object is at the global object then :
window[obj][method]() //I am a useful function dood`
Else , you will need to supply more info.

Categories