Anonymous JavaScript objects + prototype chain. How?

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Anonymous JavaScript objects + prototype chain. How?

Post by Chris Corbyn »

I can create an anonymous object like this:

[js]var obj = new (function() {  this.someMethod = function someMethod() {    //whatever  }});[/js]

So then how come I can't do this?

[js]var obj = new (function() {  this.constructor.prototype = new AnotherClass(); //INGORED});[/js]

Are there any other ways to create an anonymous subclass in JavaScript?

In pseudo I was hoping to be able to pass an anonymous instance to a method of another object:

[js]function Messenger() {  var words = [];  this.say = function say(word) {    words.push(word);  }  this.getMessage = function getMessage() {    return words.join(" ");  }} function Receiver() {  this.acceptMessageFrom = function acceptMessageFrom(messenger) {    alert("Messenger says '" + messenger.getMessage() + "'");  }} //Use case (doesn't work -- prototype ignored) var receiver = new Receiver(); receiver.acceptMessageFrom(new (function() {  this.constructor.prototype = new Messenger();   this.say("Hello");  this.say("World!");}));[/js]
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Anonymous JavaScript objects + prototype chain. How?

Post by Weirdan »

can't you just copy functions you need to your object? like this:

Code: Select all

var obj = new (function(){
    for (i in AnotherClass) {
       if (typeof AnotherClass[i] == 'function') {
           this[i] = AnotherClass[i];
       }
    }
});
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Anonymous JavaScript objects + prototype chain. How?

Post by Chris Corbyn »

Weirdan wrote:can't you just copy functions you need to your object? like this:

Code: Select all

var obj = new (function(){
    for (i in AnotherClass) {
       if (typeof AnotherClass[i] == 'function') {
           this[i] = AnotherClass[i];
       }
    }
});
That would work... I think. Not sure about private members though? It loses it's appeal suddenly however. I was planning an API and was hoping for something almost as clean as Java's:

[java]receiver.acceptMessageFrom(new Messenger() {{  say("Hello");  say("World!");}});[/java]

I knew I wouldn't be able to do quite as cleanly as that, but I also knew JavaScript would allow some round-about way of achieving it. Just wasn't sure how round-about I'd have to make it!

Thanks.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Anonymous JavaScript objects + prototype chain. How?

Post by Chris Corbyn »

Ah ha! I just wrapped your suggestion into a static method:

[js]function Messenger() {  var words = [];  this.say = function say(word) {    words.push(word);  }  this.getMessage = function getMessage() {    return words.join(" ");  }}Messenger.provideTo = function provideTo(obj) {  var me = new Messenger();  for (var a in me) {    obj[a] = me[a];  }}; function Receiver() {  this.acceptMessageFrom = function acceptMessageFrom(messenger) {    alert("Messenger says '" + messenger.getMessage() + "'");  }}  //It LIVES!! <!-- s:) --><img src=\"{SMILIES_PATH}/icon_smile.gif\" alt=\":)\" title=\"Smile\" /><!-- s:) -->var receiver = new Receiver(); receiver.acceptMessageFrom(new (function() {  Messenger.provideTo(this);        this.say("Hello");  this.say("World!");}));[/js]

Works brilliantly :) Now I just need a punchy name for my provideTo() function since it doesn't make any sense! Maybe just "extendWith()".
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Anonymous JavaScript objects + prototype chain. How?

Post by Weirdan »

Chris Corbyn wrote: That would work... I think. Not sure about private members though?
references to private variables are maintained it seems:

Code: Select all

 
function q() {
  var private = "asd"
  this.a = function() {console.log("called " + private);}
}
 
function mixin(from, to) {
   for (i in from) if (typeof from[i] == 'function') to[i] = from[i];
}
  
var obj = new (function() {
  mixin(new q, this);
  this.a(); // prints "called asd"
});
 
Post Reply