String.prototype.foo = {};
String.prototype.foo.bar = function() {
//How can you reference the "grandparent" string?
console.log(this.parent.parent); //obviously, doesn't exist
}
As in, "Hello, Nurse!".foo.bar()
would log "Hello, Nurse!".
Will it make a difference if there's control over foo?
Edit: There, foo is defined.
Edit2: Fine, instead of this.this.this
, this.parent.parent
. Of course parent doesn't exist, but hopefully now the semantics won't get in the way.
Edit3: There isn't a specific case. The provided details are pretty much all I got: There's an object foo, part of a prototype. foo.bar
is a method of foo
, and is supposed to access its grandparent. That's it. Nothing else. That's all the information I have.
Edit4: Resolved. Based on the answer provided (and some second-hand help from Douglas Crockford):
String.prototype.foo = function() {
var that = this;
return {
bar : function() {
console.log(that.valueOf());
}
}
}
//Called:
"Hello, Nurse!".foo().bar();
The only way this can be done, is to turn foo()
into a function. Think of it as initialising the foo
namespace for a particular string:
String.prototype.foo = function () {
var str = String(this);
var o = Object(this)
o.bar = function () {
console.log(str);
};
return o;
};
Then you can use:
"foobar".foo().bar(); // logs "foobar"
Or if we rename foo
and bar
into something more exciting:
"Hello!".console().log(); // logs "Hello!"
Each function is called with a particular context that is a single object. Whether it is called with a.b()
or a.b.c.d()
doesn't matter - it is given the object immediately to the left of the function call as its context. So the context for a.b()
would be a
, and the context for a.b.c.d()
is c
. The keyword this
references the context. Because c
is just an object (not a running function) it has no context, and it has no concept of this
, so this.this
makes no sense.
Therefore, it is not possible to generically access the so-called "parent". Juan's answer gives a good conceptual explanation why. However, if what you want to achieve is namespacing in prototype functions, then you can do this by returning an augmented object from foo
.
Notice I also had to convert this
into an Object
above. This is because you can't attach properties to primitive values like strings. var str = "foo"; str.bar = 1
will work, but only because JS automatically converts "foo"
into an object. However, since str
references the primitive, not the automatically created object, the object is then immediately discarded, and we lose bar
.
There is no way for an object to know what object it's a property of. The same object (in your case a function) could be attached to multiple objects. Here's an example:
var myObj = {};
var objA = {prop: myObj};
var objB = {nother: myObj}
If given a reference to myObj, how could you possibly know which parent object you're referring to? In one case, it's nothing, another case, it's objA, the last case, it's a 'child' object of objB. If you explain why you'd like this behavior, we can help you solve the problem at hand. But the answer to the question is that you CAN'T do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With