1

i'm new to JS and got the following problem:

Why is this not working / what is this code doing?

var Test = {};
Test.prop = "test property";

Test.Class1 = function () {
}

Test.Class1.prototype = {
    m1: function() {
        console.log(this.prop);
    }
}

Test.Class1.m1();

My understanding of this code would be:

  1. creating a new object called Test
  2. adding the property prop to Test
  3. creating a new object called Class1 in Test
  4. adding a method m1 to Class1
  5. calling the m1 method of Class1 in Test

4 Answers 4

1

In JavaScript, even the prototype property of a function is an object. Prior to creating an object whose prototype is the one you've defined, Test1.Class1.prototype is just a regular object. Basically it works the same way as the following code snippet:

var Test1 = { prototype { m1: function() {} } };
// You're trying to call an undefined function!
Test.m1();

// This is fine
Test1.prototype.m1();

In the other hand, when you use the new operator, you're creating a new object whose prototype is the one set to the constructor function. And here starts the magic:

var Test1 = function() {};
Test1.prototype = {
    doStuff: function() {}
};

var object1 = new Test1();
// This works!
object1.doStuff();

When you access a property, JavaScript's runtimes inspect the object to find out if there's a function called doStuff, otherwise it looks for it on the object's prototype, otherwise it looks on the prototype of the prototype and so on...

Actually new operator is a syntactic sugar. ECMA-Script 5 introduced Object.create which makes everything more clear:

var Test1 = {
    doStuff: function() {
    }
};

// The first parameter of Object.create is
// the object that's going to be the prototype of
// Test1 object!
var object1 = Object.create(Test1);
// This works too!
object1.doStuff();

Probably you should check this other Q&A: How does JavaScript .prototype work?

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

Comments

1

You need to create an instance of the prototype before you're able to use its methods:

var instance = new Test.Class1();
console.log(instance.m1());

Even as such, Test.prop is not part of the instance, and will not be accessible to m1

Edit: Here's a working example:

var test = function() {
  this.prop = "A property";
}

test.prototype.m1 = function() {
  console.log(this.prop);
}

var instance = new test();
console.log(instance.m1());

Comments

1

prototype chaining only works for instances created with the new operator.

Otherwise you will have to explicitly call prototype to access the method.

let testClass = new Test.Class1();

testClass.m1();

Also since you are trying to access the prop property.

Test.Class1.prototype = {
    m1: function() {
        console.log(this.prop);
    }
}

The call site is Test.Class1, the prop should be part of Test.Class1 and not on Test

1 Comment

Not only. What about Object.create :D
1

I changed up the names of things, but this should work.

var Person = function(){
    this.message = "Hello, world!";
};

Person.prototype = Object.create(Object.prototype);
Person.prototype.constructor = Person;

Person.prototype.greet = function(){
    console.log(this.message);
    alert(this.message);
}; 

var tom = new Person();
tom.greet();

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.