4

Consider this errorful code:

x = {
  y : "why",
  z : function() {
    return y + " zed";
  }
}

The function z does not work: "ReferenceError: y is not defined".

Is there a way to access y from within the function z without fully specifying it as x.y?

I could of course rewrite this as

x = function() {
  var self = this;
  this.y = "why";
  this.z = function() {
    return self.y + " zed";
  };
  return this;
}();

... but gosh.

4 Answers 4

3

Simply use this if you call the function with x.z():

var x = {
    y : "why",
    z : function() {
        return this.y + " zed";
    }
};

DEMO: http://jsfiddle.net/hZxVu/

Sign up to request clarification or add additional context in comments.

4 Comments

This is not infallible - consider var z = x.z; z(); //"undefined zed"
@meouw Indeed but otherwise I don't see any other options than OP's "rewritten" variant.
@meouw great point. I missed that too. I supposed you could complicate things with a closure to ensure y is always around: jsfiddle.net/YpX3B
Contrary to @meouw, I think you shouldn't be doing var z=x.z; z(); because you should never assume functions can be called when detached from their original owning objects. You should instead be doing varz=x;z.call(x); so I think this is not a valid objection.
0

No, you will need to rewrite it as such. y is a property of that object, and you can't access it without the object - unlike accessing a variable (e.g. self in your rewrite) from a closure.

Of course, when you invoke the function as x.z(), the this keyword will point to the object too, so that you can write it as

return this.y + " zed";

as long as you always call the function in context of that object.

Comments

0

@VisioN has the straight-forward answer. It might help to visualize why this is necessary if you rewrite your code as such:

var x = {};
x.y = "why";
x.z = function() {return this.y + " zed"; };
alert(x.z());

Here y and z are properties of an object, but there is no functional closure scoping. You need the "this" keyword to access a property of the parent object.

Alternatively,

var x = function () {
    var y = "why";     
    var z = function () { return y + " zed?"; };    
    return z();
};
alert(x());

This demonstrates functional scoping by accessing y without using this. Inside of x, y is known. Outside, it is not.

Comments

0

Using the revealing module pattern:

    var x = (function () {
        y = "why";
        z = function() {
            return y + " zed";
        };
        return {
            "y": y,
            "z": z
        };
    })();

    //now you can call:
    x.y // "why"
    x.z() // "why zed"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.