views:

35

answers:

1

I've adapted the Crockford object() function so that I can pass in some parameters and autorun an init function in the new object:

function object(o) {
    function F() {}
    F.prototype = o;
    var params = Array.prototype.slice.call(arguments,1);
    var obj = new F();
    if(params.length) {
     obj.init.apply(obj,params);
    }
    return obj;
}

This works fine most of the time, but within one object I have functions defined as follows:

MY.Object = function() {

 function init(element, generator) {
  build(element);
                // more code after
 }

 function build(element) {
  this._property = "example";
 }
     return {
        init: init;
     }
}();

If I then run

My.Object2 = object(MY.Object, "test param");

For some reason _property gets added to the window object. This stops if I make build a public method and call it using this.build().

Can anyone explain why this happens?

+2  A: 

build, although you've defined it within your class, has no context when you're calling it. So, no context means that this references your window object (within a browser, at least). But, even though you don't have the proper this context, you can still access your variables you've declared within the "private" scope of your class.

Try using build.call(this, element) (function.call is similar to function.apply).

Just know that JavaScript doesn't quite behave the same way as other OO languages you may have used, and that classes, and the notion of private and public (among other language features) are a bit of a hack.

palswim
Why does it not have a context in this particular instance? I'm sure I've called functions "inside" a class without using "this." plenty of times in the past without getting this problem. Is it because I'm getting build() "second hand" from a prototype rather than using it in the object it was originally defined in? And does this mean I'll have to use .call for every function or make them all public when inheriting from a prototype?
wheresrhys
@wheresrhys: you don't have to use `call` or `apply` for every private member call. It just means you can't use `this` in your private methods without these.
palswim