How Can a JavaScript Object Refer to Values in Itself

How can a JavaScript object refer to values in itself?

Maybe you can think about removing the attribute to a function. I mean something like this:

var obj = {  key1: "it ",  key2: function() {    return this.key1 + " works!";  }};
alert(obj.key2());

Self-references in object literals / initializers

Well, the only thing that I can tell you about are getter:

var foo = {  a: 5,  b: 6,  get c() {    return this.a + this.b;  }}
console.log(foo.c) // 11

Javascript literal object, reference to itself

Following up on Qeuntin's response you would use the following to achieve what you're looking for

var foo = {

self: false,

init: function(){
self = this
self.doStuff();
},

doStuff: function(){
alert('doing stuff');
},
}

EDIT: Since it's been pointed out that whilst this solves OP's problem (i.e it works) it isn't exactly how you should go about it. So, here's a scoping reference.

function A()
{
//Semi-private / hidden var
var pVar = "I'm a private, err hidden, variable",
//fn (technically a var)
pFn = function(){},
//empty var, placholder for hidden fn
privatePlaceholderFn;

//Instance-time... public fn
this.instancePublicFn = function()
{
console.log("--- instace public ---");
//Print hidden var to cosole
console.log(pVar);
//Call hidden fn
instancePrivateFn();
console.log("--->Setting private from instance public")
//Set the hidden fn
setPrivate();
console.log("--- / instance public ---");
}
//Pass fn to private method.
this.setPrivFromOutside = function(fn)
{
setPrivateFromPrivateYetOutside(fn);
}

//Set the hidden fn
this.iPFnPlaceholderSetter = function(fn)
{
privatePlaceholderFn = fn;
}

//Call the semi-private / hidden fn
this.callPrivate = function()
{
privatePlaceholderFn();
}
//A misnomer, proves the scope exists. See "function setPrivate()"
this.setPrivateFromInstance = function()
{
//Prove scope exists
console.log(privatePlaceholderFn);
console.log("Private From instance - gets inside scope");

}
//Set hidden fn from private method
function setPrivate()
{
privatePlaceholderFn = function()
{
//Show scope exists
console.log(pVar);
}
}
//Set the hidden fn from hidden method
function setPrivateFromPrivateYetOutside(fn)
{
//fn's scope won't resolve to inside
privatePlaceholderFn = fn;
}
//Private / hidden messager
function instancePrivateFn()
{
//Just loggin' something
console.log("Instance Private method");
}
}
//Add an object method to the prototype
A.prototype.protoPuFn = function(){
console.log("---> Private var from object literal method");
//console.log(pVar)
}

//...
a = new A();

//Add object literal fn
a.objFn = function()
{
console.log("Object literal defined public fn - Gets outside scope");
//console.log(pVar);
}
//Set private / hidden placeholder fn
a.iPFnPlaceholderSetter(function()
{
console.log("Hidden fn, passed through instance public - gets outside scope");
//console.log(pVar);
});
//Attempt to read hidden var
console.log(a.pVar);
//Call object literal defined fn
a.objFn();
//Call the hidden fn
a.callPrivate();
//Call prototype added fn
a.protoPuFn();
//Call instance added public fn
a.instancePublicFn();
//Call private / hidden method (set
a.callPrivate();
//Same as iPFnPlaceholderSetter except the param is passed to a hidden method, before seting.
a.setPrivFromOutside(function()
{
console.log("-->Passed from outside, through public then private setters");
//console.log(pVar)
})
//Call the hidden method
a.callPrivate();
//Set hidden fn from instance public
a.setPrivateFromInstance();
//Call the hidden method.
a.callPrivate();
//Use evi(a)l fn to steal scope.
a.evil("this.meth = function(){console.log(pVar)}");
//Call fn with stolen scope
a.meth();

Javascript object that references itself... any problems?

In terms of memory, it's fine. The object is just saying where it is located. It's up to you whether to ask it about it again and again.

Why changing the value of an object reference doesn't actually change the object?

Each rectangle in the following diagrams denotes an object.

const obj = { a: {} } is creating the object { a: {} } in memory and assigns its reference to the variable obj.

const obj = { a: {} }

let aOfObj = obj.a is assigning the reference of the inner object a to the variable aOfObj.

let aOfObj = obj.a

Since aOfObj and obj.a are referencing the same object, altering the object referenced by aOfObj will be reflected on obj.a too, because they are the same object.

aOfObj.b = 4

Now when you do aOfObj = {}, you are creating a new object (in memory) and assigning its reference to aOfObj, so obj.a and aOfObj points to different objects.

aOfObj = {}

Note:

Both variables and objects are stored in memory. The variables (everything on the left side above) are stored on the stack, whereas the objects (everything on the right above) are stored on the heap.

When working with primitive values (like numbers, strings, ...), the variable is stored on the stack, and its value is the primitive value itself. For example: let n = 5; is creating a variable n on the stack and sets its value to the literal number 5.

When working with objects (objects, arrays, instances of classes, ...), the variable is stored on the stack, whereas the object is stored on the heap (because the stack is smaller) and the reference (the address of that object in memory) is stored as the value of the variable on the stack. For example: let o = {} is creating the variable o on the stack and the object {} on the heap and set the value of o on the stack to the address of that object which is a number (eventually keeping the stack smaller).

In javascript, unlike some other languages, the variables themselves can't be referenced, only values that are objects can, and that's why javascript is not a pass-by-reference language.

Can a JavaScript object's child reference itself?

Good question by the way.

This is called circular referencing.

Meaning the you are creating the nested reference of the same object.

Garbage collection in browsers: The main function of the garbage collector in the browser is to free the memory if the memory occupied by the object is no longer in use. But in the case of circular reference

An object is said to reference another object if the former has an
access to the latter (either implicitly or explicitly). For instance,
a JavaScript object has a reference to its prototype (implicit
reference) and to its properties values (explicit reference)

(Source MDN)


This is forcing the garbage collecting algorithm to prevent the object from being garbage collected, which in turn is a memory leak.

As per the MDN Mark and sweep algorithm is been improved in such circumstance of circular referencing which is intelligent enough to remove the object of this type.

Circular referencing was a problem in IE < 8 which caused the IE browsers to go hay wire on this. Read this link and this one


IBM link

This article sheds light on JavaScript circular referencing memory leak with example and clarity on the subject.


Final Verdict: Better to avoid circular referenced objects, only use when its highly needed at programmers discretion. As modern browsers today are quite efficiently built though but its not a good practice as a developer to write code that causes unwanted memory consumption and leaks.

Can I reference other properties during object declaration in JavaScript?

No. this in JavaScript does not work like you think it does. this in this case refers to the global object.

There are only 3 cases in which the value this gets set:

The Function Case

foo();

Here this will refer to the global object.

The Method Case

test.foo(); 

In this example this will refer to test.

The Constructor Case

new foo(); 

A function call that's preceded by the new keyword acts as a constructor. Inside the function this will refer to a newly
created Object.

Everywhere else, this refers to the global object.

How does an object reference itself in Javascript?

Well, actually the two are doing exactly the same:

Dog.prototype = new Animal;

The this value inside the methods will refer to the base object where the reference was invoked, in the case of:

Dog.inherits(Animal);

The this value will refer to the Dog constructor function, and the obj argument will be the Animal function.

When you call:

Animal.pass(Dog);

The this value will refer to the Animal function, doing at the end exactly the same thing as the inherits method, but the other way around.

I would recommend you to not extend the Object.prototype object, because it can cause you a lot of problems, for example those two properties will be enumerated in any for-in loop, e.g.:

for (var prop in {}) { // <-- an empty object!
alert(prop); // will alert 'inherits' and 'pass'
}

All objects inherit from Object.prototype, and it seems that you intend to use those methods only on Function objects, it would be safer to extend the Function.prototype object, or implement the methods as functions that take two parameters.

Object referencing its own property on initialization

Alternatively, you can use a self starting function to give you a similar affect to what you are looking for:

var a = (function() {
var b = 10;
return {
b:b,
c:b*2
}
})();

console.log(a.c);


Related Topics



Leave a reply



Submit