Question

There are two pieces of codes.

Why is the first one correct but the second one incorrect?

What's wrong with this.prototype?

function Person(name, age, job){

    this.name = name;
    this.age = age;
    this.job = job;

    if (typeof this.sayName != "function"){

        Person.prototype.sayName = function(){
            alert(this.name);
        };

    }
}

function Person(name, age, job){

    this.name = name;
    this.age = age;
    this.job = job;

    if (typeof this.sayName != "function"){

        this.prototype.sayName = function(){
            alert(this.name);
        };

    }
}
Was it helpful?

Solution

Both of them are actually incorrect. But more on that later.

The second one is incorrect because objects don't have prototype property. Only functions have a such a property.

In the second example, this is an object, so this.prototype is undefined. In the first example you are setting Person.prototype and Person is a function, so all is "good".


Why is the first example still wrong? Because you usually don't have a reason to extend the prototype object inside the constructor. The constructor should only contain instance specific code and the prototype object should hold properties which are shared by all instances.

So your above example is correctly written as:

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
}

Person.prototype.sayName = function(){
    alert(this.name);
};

OTHER TIPS

It's about how prototype is implemented.

When you saying Person.prototype.sayName 'Person.prototype' gives you the [[Prototype]] property of 'Person' to be modified with.

when calling this.prototype.sayName a property named 'prototype' is checked for 'this' object and if not found the object referenced by [[Prototype]] property of 'this', which is still not found cause you haven't defined it

P.S.

Haven't tested myself, but this.__proto__ shall work in some implementations

in this.prototype you are referring to the instance. The instance has no prototype, the constructor function does. You can replace:

if (typeof this.sayName != "function"){
        this.prototype.sayName = function(){
            alert(this.name);
        };
}

with

if (!Person.prototype.sayName) {
        Person.prototype.sayName = function(){
            alert(this.name);
        };
}

A method assigned to the prototpe will exist within all derived instances. this.sayName in the first snippet doesn't exist on first instantiation, but your if ... catches it and assigns Person.prototype.sayName, which is subsequently available to new instances of Person. That's why the first example works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top