views:

163

answers:

3

Please see the following script:

var x = function(param){
    this.data=param;

    this.y = function(){
        alert(this.data)
    }

    return this;
}

/*
    x.prototype.z = function(){
        alert(this.data);
    }
*/

x(123).y();
x(123).z(); // This should behave same as y()

When I call x(123).y() then message displays 123. The function y() declared inside x()

Now I want to declare another function z() which will reside outside x() but will behave same as y() [associate with x()]

Is it possible? If possible how?

+1  A: 

It is possible, and your commented-out z function should work as is if you fix how you're creating xs.

Note that your function y doesn't have to be declared inside the constructor if it's only dealing with instance properties (which in your code it is), and doing so has a significant memory cost (every instance gets its own copy of that function). You only want to do that if you absolutely have to for major data hiding reasons, given the costs involved.

Edit: Sorry, I missed something: You're missing the new keyword, your examples should be:

new x(123).y();
new x(123).z();

...and your constructor shouldn't return this.

Complete example:

var x = function(param) {

    this.data=param;

    // Doesn't have to be in the constructor, and you should
    // avoid it unless you're doing something with major
    // data hiding a'la Crockford
    this.y = function() {
        alert(this.data)
    }
}

x.prototype.z = function() {
    alert(this.data);
}

new x(123).y();
new x(123).z();

This is the Crockford article I mention above, but again, it has big memory implications.

T.J. Crowder
I know about the new keyword issue.But I need to have the solution without using new.Any more IDEA?
Saiful
Don't use `this` if you don't want to use `new`.
meder
@Saiful: Wrap the whole thing up in another function that does the `new` for you and returns the result. You need `new` for this.
T.J. Crowder
+3  A: 

You're missing a new when calling x(). Otherwise, this within the function body will refer to the global object (window in browser contexts) and not an instance of x.

That's the reason why calling z() (after un-commenting the code) doesn't work. Calling y() only works by coincidence as you create a global variable data, whose value will be overwritten by the next call to x().


I have no idea what you're trying to accomplish, and from what I can see, it most likely isn't a good idea. Anyway, here's an example of how to get rid of explicit new when creating objects:

var x = function(param){
    // add missing `new`:
    if(!(this instanceof x))
        return new x(param);

    this.data=param;

    this.y = function(){
        alert(this.data)
    }
}


x.prototype.z = function(){
    alert(this.data);
}

x(123).y();
x(456).z();
Christoph
I know about the new keyword issue.But I need to have the solution without using new.Any more IDEA?
Saiful
sorry, if you don't want to use `new`, you can't use `prototype` so you'll have to add the `z()` method to all objects manually...
Christoph
added an example of how to 'hide' the `new` and use a simple function call for object instantiation
Christoph
A: 
function generator( param ) {
    this.data = param;
    this.y = function() {
        alert( this.data )
    }
}

generator.prototype.z = function() {
    alert( this.data );
}

x = new generator( 3 );
x.y()
x.z()

Not sure if this is what you want, but this is a constructor named generator which returns an object, and a prototypal method is defined outside of it with the new keyword.

As others stated:

  • you don't need to return this in the constructor
  • you call it with the new keyword
  • all methods declared with this are public unless you use var in which case they become private
meder