JavaScript does not define a method within an array - javascript

I have the following situation:
var a = {
b: function() {
alert('hi');
},
c: [{m: this.b}]
};
alert(typeof a.c[0].m);
The output is "undefined". What is the reason for this?

Because you are using this keyword inside an object. In that case this.b is referring to something undefined which should be a property of window.
Read this article, it is very useful to understand scopes.
In this case, you should declare your variable like this:
b = 't'; //note there is not keywork var, it is a window global variable
var a = {
c: [{
b: 'a',
m: this.b //is 't'
}],
b: function() {
alert('hi');
}
};
alert(a.c[0].m); //will display 't'

Because (assuming you are executing this in the context of a browser) this is window and you haven't defined window.b.
The value of this is determined by the way you execute the current function, not by an object literal.
MDN has further reading about this.

When the value for a.c[0].m is run, this doesn't refer to a, it refers to the entire scope.
If you want the behaviour you are after, you need to change it to:
var a = { b: function() { alert('hi'); }, c: [{}] };
a.c[0].m = a.b;

Related

Why does the pointing of `this` not change

let o = {
a: 123,
b: function () {
console.log(this, this.a);
},
};
(o.b)()
Like this code, my understanding is that the code is like this:
const b = o.b
b() // this is pointing to window
But for (o.b)(), this keyword is pointing the o object, why is that?
Putting parentheses around an object reference to a function will only change the this from the object if there's something else inside the parentheses that makes the interpreter first resolve the value inside the parentheses to something else first (for example, if you use any of the operators, or invoke a function inside the parentheses).
let o = {
a: 123,
b: function () {
console.log(this === window);
},
};
// Using comma operator now
(0, o.b)()
But if all you have is a plain method reference on an object, with nothing else inside the parentheses, the calling context doesn't change - the extra parentheses around the reference doesn't change it.

Javascript object with shared name

So, I'm trying to create an object like:
var a = {
b: "object_id",
b: function(){ return c(this.b); }
}
var c = {
"object_id": {
foo: "bar"
}
}
But it only registers the last value for the key 'b'. But I think I've seen something like this used before and it would really help me if I could call a.b().foo or if I just want ID a.b
Is there any way to make this happen or will I have to rename value and/or method?
You're looking for the Object Getter/Setter notation.
var o = {
_b: 7,
get b() {
return this._b + 1;
},
}
That being the case, you CAN'T use the same object id, and should store the internal variable for b in a closure, if you need it to be totally private.

How to anonymize a function / remove its name in an object?

I am copying functions from one object to another. The problem is that while they are anonymous in the source object, they have a name in the target object:
var o1 = {
a: function() {
alert("Hello World");
},
b: 123,
c: "Some string"
}
var o2 = {};
for (var key in o1) {
if ("function" == typeof o1[key]) {
o2[key] = o1[key];
}
}
console.log(o2.a); //output: function o1.a()
The two functions do not seem to be connected in some way, but this is very irritating at least. Also, Firefox Developer Edition knows where the function came from if I log it in the console and click the name. And I don't know whether this might have some other bad influence somehow.
So, if it is possible to copy a function and keep it anonymous, that would be great!
You can use Object.assign().
var o1 = {
a: function() {
alert("Hello World");
},
b: 123,
c: "Some string"
}
var o2 = Object.assign({}, o1);
For manipulate independents objects.
Look this too:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

javascript declaring key value pair in a function

let us say i have a object in which there is a function and inside the function i have declared some key values.
if every function is an function object in javascript then it is totally legal to declare key value pair in it.
var a ={
a: "shiv",
b: "shiv1",
c: function(){
L:"shiv1",
console.log(L);
}
}
how can i access these keys. in what scenarios i need to add key value pairs to a function. what does this signify. For Example in this function, how can i access L key.
Edit 1:
Console.log line will through err.
let say we have only this code
var a ={
a: "shiv",
b: "shiv1",
c: function(){
L:"shiv1",
}
}
what does declaring a key in function signify. if i need to access L key how can i
You every function is also an object, meaning that you can indeed set properties to it. In fact every function has length property, which denotes the number of formal arguments this function accepts.
However the syntax you are using to set function properties is not how you should do it. Even though you are using perfectly valid syntax, this is label statement, not property definition syntax. If you wanted to set a property to a function object in your case you would do it like this:
function c() {
console.log(c.L) // => "I'm a property of c function"
}
c.L = "I'm a property of c function";
var a = {
a: "shiv",
b: "shiv1",
c: c
}
When it can be useful? Like I said there is a limited use for it, like length property of the function, but in many cases you would not need setting properties on a function level directly.
This has to be throwing errors:
L:"shiv1",
console.log(l);
You probably want:
c: function(){
return {L:"shiv1"};
}
And then access it as:
a.c().L;
Full example here:
var a ={
a: "shiv",
b: "shiv1",
c: function(){
return {L:"shiv1"}
}
}
alert(a.c().L);
You can't declare keys like you did inside the function.
This doesn't work:
c: function(){
L:"shiv1", //Declaration don't work in this context
console.log(l); //Don't work
}
Try this (Please, remove the "function" statement):
c: {
L:"shiv1"
}
Also, you can do this:
c: function() {
var test = "shiv1";
return test;
}
If you want to work with parameters:
c: function(a, b) {
var test = a + " shiv1 " + b;
return test;
}
Or:
c: function(a, b) {
var total = a + b;
return total;
}

Why can't I use a defined function inside another defined function,when creating an js object?

The code goes like this
var ob = {
a: function() {
b()
},
b: function() {
console.log("hi")
}
};
As you can see, you can't do
ob.a() //returns error
Can someone explain the reason in depth?
Becuase b does not exist in the current scope (which is the global one in this case).
This works, however:
var ob = {
a: function () {
this.b()
},
b: function () {
console.log('hi')
}
};
because this refers to the ob object.
There is no function b defined anywhere, it's a property of object ob, so you can refer it as this.b from inside a:
var ob = {
a: function () {
this.b();
},
b: function () {
console.log("hi");
}
};
ob.a();
You could also access b as ob.b().
The b is a property of the object called ob. That being said, if you use
ob.b
instead of b you will solve your problem.
var ob = {
a:function(){
ob.b()
},
b:function(){
console.log("hi")
}
};
Another way to do achieve this is to use the this operator.
var ob = {
a:function(){
this.b()
},
b:function(){
console.log("hi")
}
};
The this holds a reference to the object you define. Hence using it you can access is properties. It is a better way that the first way, because if you decide later to alter the name of ob to obj, you will not have change it in two places.

Categories

Resources