Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"this" inside object [duplicate]

I'm trying to calculate a proportional height (while excluding a static height element) from a width that gets passed in via a request (defaults to 560).

However, wF.h evaluates to NaN. If I replace this.w with 560 it works, but not when trying to reference the w property of wF.

var wF = {
       w : 560,
       h : (312 - 42) / (560 / this.w) + 42
};

What gives?

I refuse to use two plain vars in succession, because I'm trying to get nice code out of JS.

Update:

Thanks to everyone who helped explain and solve my problem. I guess i'll just have to get used to that. I'll be setting the object up in stages to get on with the project, even though it still annoys me slightly ;). I found and read a nice article on the topic for anyone who stumbles upon similar issues: http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/

like image 577
mhe Avatar asked Aug 12 '11 16:08

mhe


People also ask

Can we use this in object in JavaScript?

“this” is not bound In JavaScript, keyword this behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. The value of this is evaluated during the run-time, depending on the context. The rule is simple: if obj.

What is the syntax of object defineProperty method in JavaScript?

Syntax: Object. defineProperty(obj, prop, descriptor)

How to copy properties from one object to another in JavaScript?

assign() The Object. assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.


4 Answers

// Your code
var wF = {
       w : 560,
       h : (312 - 42) / (560 / this.w) + 42
};

this isn't what you think it is

Javascript has no block scope, only function scope: this inside the definition for wF does not refer to wF.

(And so this.w, whatever this is, is likely undefined. Dividing by undefined yields NaN.)

So then you might try:

// Let's not use `this`
var wF = {
       w : 560,
       h : (312 - 42) / (560 / wF.w) + 42
};

You haven't finished defining the object yet

However, you're still defining the object where you attempt to use wF.w: it's not ready for that yet.


Solution

So, yes, you will have to use two variables... or set up the object in stages:

// We can't even use `wF`; split up the property definitions
var wF = {};
wF.w = 560;
wF.h = (312 - 42) / (560 / wF.w) + 42;
like image 56
Lightness Races in Orbit Avatar answered Oct 05 '22 10:10

Lightness Races in Orbit


Hi just redefine your second property as a function object and it will work. I think it is possible to access the context of the calling object from within a function

var wF = {
    w : 560,
    h : function() { return (312 - 42) / (560 / this.w) + 42; }
};

alert(wF.h())
like image 27
houss Avatar answered Oct 05 '22 08:10

houss


The this keyword refers to the calling context, not an object.

You need to do this in two steps like so:

var wF = { w: 560 };
wF.h = (312 - 42) / (560 / wF.w) + 42;
like image 33
Paul Perigny Avatar answered Oct 05 '22 09:10

Paul Perigny


You don't need to wrap the {...} in an Object(). It is already an object literal.

this doesn't operate inside the object literal, it will point to the object that the function is currently running in so:

function fn() {
   var wF = { w : 560, h : (312 - 42) / (560 / this.w) + 42 };
}

fn();

will cause this to point to the window object.

EDIT: Previous code was not intended to be an answer, just a demonstration of what this is. Another possiblity would be to use a function that takes the width as an argument:

function getObject(width) {
    width = width || 560; //Default value to 560
    return { w: width, h : (312 - 42) / (560 / width) + 42 };
}

var wF = getObject(); //To get the default value, or specify a width otherwise.
like image 40
Dennis Avatar answered Oct 05 '22 08:10

Dennis