UncaughtType Error: cannot read property x of undefined

What would cause this eŕror if I declare an object

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

and a function

function Project(v)
{
      var vp=new vertex();
      vp.x=v.x*d/v.z;
      vp.y=v.y*d/v.z;
      return vp;
}

that passes that object as parameter?

not passing an appropriate object as parameter.

1 Like

I know but im doing

var v = new vertex();
v[0]=vertex(0,0,0);


v]7]=vertex(0,0,0);

var vp =new vertex();

for(i=0;i<8;i++)
vp[i] = Project(v[i]);

then check in your Dev Tools, if the passed parameter is the one you expect.

also mind that v and vp are not arrays, contrary to your assumption.

I tried with var v = ; and var vp= but I got the same result so I changed it.

what made you thing that not using an array were the reason, when the problem lies with the parameter itself?

The variable d is not defined, which will cause a reference error; you’d probably want to pass it to the Project function as well. Anyhow the problem is not the argument you’re passing but the argument you’re not passing. ^^

Now you can indeed access any object properties using the [ ] notation – including numeric properties, over which you can then loop as in your second snippet, so no error there AFAICT. It just wouldn’t make too much sense to use a vertex instance as another vertex container, I think. (I used to suck really hard at this 3d geometry kind of stuff.) :-D Using a vanilla Array should be fine here anyway.

(BTW, by convention constructor functions start with capital letters, normal functions not – just the other way round!)

I know, d is defined elsewhere…

I’m used to c++, Javascript is confusing to me…

Anyway the code runs fine in the AIDE-web tool but not in SoloLearn…

d must also be in scope to work.

yup, totally different approach to do things. best you forget C++ when coding JS.

[quote=“Helioform, post:3, topic:244765, full:true”]
I know but im doing

var v = new vertex();
v[0]=vertex(0,0,0);

The first line is fine as the new keyword gives context to the this keyword within the vertex function. It’s the second where trouble occurs.

When execution passes from the second line to the vertex function , it has no context for the this keyword. When the this keyword is undefined, attempting to access things like this.x will result in the error that you are seeing.

If a function is supposed to be a constructor, always call it with the new keyword. It also helps to give the constructor function an a capital initial letter so that the naming convention acts as a reminder that it is a constructor.

1 Like

well, the context would be the global object window.

When you run the code in strict mode, as you should do:

"use strict";
...

the interpreter will behave differently, resulting in the this keyword being undefined instead.

When not using strict mode, the Project() function vp.x will trigger the error instead.

but that’s due to vector()'s return value not being an object at all (instead being undefined since the function does not have a return value).

That’s right. What do you think is expected to occur when vector(0, 0, 0) is called? Should it instead be called with the new keyword?

V[0] = new vector(0, 0, 0);

Actually no, I’m wrong with that.

When not running in strict mode, it is not vp.x that triggers the error. Instead, it is v.x that triggers the error for the value v is undefined. Why, because the vertex constructor was called without the new keyword.

v[0]=vertex(0,0,0);

And that is why I prefer object factories over object constructors.

I prefer to do it without constructors too, and sometimes even without object.create, or even the this keyword :slight_smile:

function vertex(spec) {
    if (spec === undefined) {
        spec = {};
    }
    spec.x = spec.x || 0;
    spec.y = spec.y || 0;
    spec.z = spec.z || 0;

    return spec;
};

Which allows you to do:

var v1 = vertex(); // {x:0, y:0, z:0}
var v2 = vertex({x: 4}); // {x:4, y:0, z:0}
var v3 = vertex({y: 3, z: 5}); // {x:0, y:3, z:5}
var v4 = vertex({x: 4, y: 3, z: 5}); // {x:4, y:3, z:5}

Ok thanks guys! I added the new keyword and it worked.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.