Reputation: 2051
I'm trying to achieve a specific syntax pattern in JavaScript. Essentially, the requirement is to extend the prototypes of native JavaScript objects with new methods, and to organise those methods into namespaces. The result I'm looking for can be summed up as:
String.prototype.foo = {
bar: function() { return this.toUpperCase(); } //Fails because "this" is foo, not it's parent string
};
'test'.foo.bar(); //should return 'TEST'
I am aware there are other ways to achieve similar results but I really would prefer the syntax above is possible - although I'm about 80% sure that it's not.
I've tried a dozen different ways of constructing this but I can't find any way of reaching the string as "this" inside bar(). I believe the problem is that because foo is an object and has no executable code, there is no way for the compiler to pass the owner "this" to it and from there down to the child method, but I wondered if some obscure technique for walking the parent chain exists that I don't know about? The next best thing might be 'test'.foo().bar(), which I haven't tried, but sounds more likely to work.
Upvotes: 4
Views: 130
Reputation: 276306
Sure, here you go:
Object.defineProperty(String.prototype,"foo", {
get: function(){
return {
bar: function(){ return this.toUpperCase() }.bind(this)
}
},
enumerable: false, // don't show in for.. in loop
configuratble: true,
});
"hello".foo.bar(); // "HELLO"
A couple of things to notice:
defineProperty
for defining a getterFunction::bind
for fixing the this
value.Upvotes: 4
Reputation: 2596
Hi here is the solution with function
String.prototype.foo = function(){
var that = this;
return{
bar:function(){
return that.toUpperCase()
}
}
}
'test'.foo().bar();
I think the solution with object does not exist. Note that 1 object can exists in many "parents" so how to decide which one is the one you want
Upvotes: 0
Reputation: 3815
While this answer makes your "namespace" a function rather than an object, this should work:
String.prototype.foo = function(){
var self = this;
return {
bar: function() { return self.toUpperCase(); }
};
}
'test'.foo().bar()
Upvotes: 0