javascript prototype declaration

ぃ、小莉子 提交于 2020-01-06 13:31:04

问题


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);
        };

    }
}

回答1:


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);
};



回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/22292881/javascript-prototype-declaration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!