Eli Blokh
Eli Blokh

Reputation: 12293

Function variable is undefined after definition

I have this code

var Point = function (startX, startY) {
  var x = startX
  var y = startY
}

function somefunc (data) {
    var newPoint = new Point(data.x, data.y);
    console.log(data.x + ":" + data.y);
    console.log(newPoint.x + ":" + newPoint.y);
}

And I get in console

0:0
undefined:undefined

Why newPoint values aren't assigned?

Upvotes: 0

Views: 373

Answers (4)

You are missing the magic of new keyword.

Generally when ever we create an object, we do not return explicitly an object from the function when you use new keyword, as it does for us.

var Point = function (startX, startY) {
  var obj = {}  // common part
  obj.x = startX;
  obj.y = startY;
  return obj //common part
}

we call it without new keyword as below and the work is done

var newPoint = Point(data.x, data.y);
console.log(newPoint.x + ":" + newPoint.y);

When ever we create a constructor function we are overdoing as the object declaration and return part are common in every function

i.e.,

var obj = {}
return obj

So the new keyword provide you with the boilerplate of declaring the object and returning it implicitly.

var Point = function (startX, startY) {
  var this = {}  // implicit declraration by new keyword
  this.x = startX;
  this.y = startY;
  return this  //implicit return by new keyword
}

So you must bind your variables to this, which you want to return.

Upvotes: 0

Bhavesh Shah
Bhavesh Shah

Reputation: 49

You are declaring a new variable 'x' and 'y' inside Point which will be only accessible inside the function as declaring variable like this makes it local variable. You can use closure for the same so that each instance you create of the point you have value stored in it.

var Point = function (startX, startY) {
  return {
     x: startX,
     y: startY
  }
}



var newPoint1 = new Point(10, 20);
var newPoint2 = new Point(20, 10);

console.log(newPoint2.x + ":" + newPoint2.y);
console.log(newPoint2.x + ":" + newPoint2.y);

Upvotes: 0

Suren Srapyan
Suren Srapyan

Reputation: 68685

Replace var declaration with this access. You need to attach properties to the current object which will be created via new. Without this they are created when you call the function and removed after function call.

var Point = function (startX, startY) {
  this.x = startX;
  this.y = startY;
}

function somefunc (data) {
    var newPoint = new Point(data.x, data.y);
    console.log(data.x + ":" + data.y);
    console.log(newPoint.x + ":" + newPoint.y);
}

somefunc({x: 1, y: 1});

If you use function as an object creator, ES6 provides special keyword - class, which is OOP friendly way to create objects

class Point {
  constructor(startX, startY) {
     this.x = startX;
     this.y = startY;
  }
}

function somefunc (data) {
    var newPoint = new Point(data.x, data.y);
    console.log(data.x + ":" + data.y);
    console.log(newPoint.x + ":" + newPoint.y);
}

somefunc({x: 1, y: 1});

Upvotes: 4

Jonas Wilms
Jonas Wilms

Reputation: 138537

Javascripts inheritance might be confusing at first. When you call a function with new, it creates a new object, and the special this variable will refer to that object. The function will then automatically return this. So to set properties of that object, you need to assign them to this, as the variables of the constructor function are not exposed in any way:

function Point(x, y){
  this.x = x;
  this.y = y;
}

This behaves equal to:

function Point(x, y){
  var context = {};

  context.x = x;
  context.y = y;

  return context;
}

However you could also use javascripts class syntax which might look a bit more logical:

class Point {
  constructor(stattX, startY){
    this.x = startX;
    this.y = startY;
  }
  // class methods here...
}

Upvotes: 0

Related Questions