开发者

Referring to an javascript object proprty (using this) while creating it

Can you explain me why this object does not understand 'this'?

var circle = {
                radius : 20,
                x : 100 - this.radius / 2,
                y : 100 - this.radius / 2,
             }

co开发者_C百科nsole.log(circle.x) // returns NaN, why?


  1. because that's not how this works in JS. this will only be a reference to your object when you somehow cause your object to be assigned as the this value of a function's calling context.

  2. you can't reference an object literal from itself while it is being created, because it doesn't yet exist.

If you're creating circles, you might consider using a constructor:

 function Circle(radius) {
    this.radius = radius,
    this.x = 100 - this.radius / 2,
    this.y = 100 - this.radius / 2,
 }

 var circle_20 = new Circle( 20 );

Because you're invoking Circle as a constructor using new, this inside the constructor invocation will be a reference to the object being created. That object is implicitly returned since you're not explicitly returning some other object.


Here is a simple illustration:

//Saul was born:  Initialize the parent!
var parent = {
    youngestChild: 'Small Saul'
};

//Tim was born:  Overwrite the parent!
parent = {
    youngestChild: 'Tiny Tim',
    currentYoungestChild: parent.youngestChild
};

alert(parent.currentYoungestChild);


Who is parent.currentYoungestChild?

Like many developers, I thought parent.youngestChild would be set to 'Tiny Tim' before it would be set to parent.child. If that were the case, it would be set to 'Tiny Tim'.

However, it turns out that all children are evaluated prior to being stored on their parent, so

parent.currentYoungestChild == 'Small Saul'

Here's a fiddle if you want to try it out.

One explanation for this functionality is because then order of child declarations do not matter. For example, the following would have had a different outcome if objects were evaluated and stored sequentially:

parent = {
    currentYoungestChild: parent.youngestChild,
    youngestChild: 'Tiny Tim'
}; 

Long story short: Initializing child elements from other child elements in an object declaration will not work!


Because where that is being defined, this is not the circle object.

How about:

var circle = {
  radius: 20,

  getX: function() { return (100) - this.radius / 2; },
  getY: function() { return (100) - this.radius / 2; }
}


The object does not exist yet. It only exists after caluclating everything, so when calculating it's just too early to use the object.

Instead, you could calculate the values in a closure, so that you can safely calculate them separately, and return the object:

var circle = (function() {
    var radius = 20,
        x      = 100 - radius / 2,
        y      = 100 - radius / 2;

    return { radius: radius,
             x:      x,
             y:      y      };
})();

// now circle is the wanted object,
// and you don't leave the `var` variables separately.


You are getting that result because, in that context, this doesn't refer to the object being created.

There's no way to do what you are attempting (inside the object declaration) in JavaScript. The only workaround would be something like:

var newRadius = 20

var circle = {
                 radius: newRadius,
                 x: 100 - newRadius / 2,
                 y: 100 - newRadius / 2
             };

console.log(circle.x);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜