为什么我不能从内部定义函数原型

时间:2012-07-29 16:48:31

标签: javascript inheritance prototype

我正在尝试实现一种在JavaScript中实现继承的方法。首先我定义基类,如下所示:

function Person(name){
    name = name + "!"; //I want to reuse this code for initialization

    this.getName = function(){
        return name;
    };

    this.setName = function(_name){
        name = _name;
    };
};

然后我定义子类。发生我需要一种方法来调用基类构造函数。理想情况下,当我仍然有VipPerson param的引用时,我会在name构造函数中调用它。但是,如果我从那时起这样做就行不通,如果我尝试从基类访问getName,我会收到VipPerson has no getName method的错误。

function VipPerson(name, vipLevel){
    this.getVipLevel = function(){
        return vipLevel;
    };

    //the line below would not work!
    //VipPerson.prototype = new Person(name);
};

VipPerson.prototype = new Person(); //but this would. not ideal IMO

VipPerson之外设置原型的缺点是我丢失了对参数的任何引用。

有一种优雅的方法来解决这个问题吗?我想有这个干净的界面:

var foo = new Person("Foo");
console.log(foo.getName());

var bar = new VipPerson("Bar", 100);
console.log(bar.getName()); //error
console.log(bar.getVipLevel());

3 个答案:

答案 0 :(得分:2)

function VipPerson(name, vipLevel){
    Person.call(this, name);

    this.getVipLevel = function(){
        return vipLevel;
    };
};

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

请参阅:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create/

但是,除非存在特定的安全问题,否则我会避免创建闭包只是为了制作“私有”变量。 JavaScript是一种基于OOP原型的动态语言,不应该像具有私有成员的基于类的语言一样使用。

我建议你阅读那样的文章:https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript

答案 1 :(得分:1)

当你从构造函数中设置原型时,它会有效,但它并不能满足你的需求。因为原型对象的设置是在您运行构造函数之前进行的,所以在第一次调用“VipPerson”构造函数时,第一个新创建的对象(this)将无法正确“连接”。

但是,如果你再次调用构造函数 ,你会注意到原型就在那里并且“.getName()”有效。

请注意,除非您希望所有“Person”对象共享相同的名称,否则它无论如何都不会起作用。应设置“Person”,使“setName()”更新this.name而不是闭包中的变量。 所有“VipPerson”实例只有一个“Person”实例 - 它是实例化的原型对象。

答案 2 :(得分:0)

你尝试过这种方法吗?

function VipPerson(name, vipLevel){
    this.__proto__ = new Person(name);

    this.getVipLevel = function(){
        return vipLevel;
    };
};