在javascript中进行原型设计时的问题

时间:2014-01-27 17:34:27

标签: javascript object prototype

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

var Greeting = (function(){
    Greeting.prototype = new Greeter();        
    Greeting.prototype.constructor = Greeter;
    function Greeting(greeting){
    } 
    return Greeting;
})();



var greeting = new Greeting("World");
alert(greeting.greet());

我正在尝试使用javascript原型来操纵继承。我有一个类似上面的类结构。但是当我调用greet方法时,它会显示一些如下图所示的内容。有人能指导我吗?

enter image description here

5 个答案:

答案 0 :(得分:2)

在Greeter的“问候”方法中,你称之为.geting。但是,在Greeting对象中,您尚未定义“问候”方法......

答案 1 :(得分:2)

在创建Greeter对象时,永远不会调用“构造函数”函数Greeting。因此,this.greeting = message;行永远不会运行,这就是undefined的原因。

您必须手动插入该行:

function Greeting(greeting){
    this.greeting = greeting;
}

或调用父构造函数:

function Greeting(greeting){
    Greeter.call(this, greeting);
}

答案 2 :(得分:1)

当您致电greeting.greet()时,this.greetingundefined,因此问题就出现了。

<强>解释

试试这段代码:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
console.log('Log 1: ' + Greeter);

var Greeting = (function(){
    console.log('Log 2: ' + Greeting);
    Greeting.prototype = new Greeter();        
    console.log('Log 3: ' + Greeting);
    Greeting.prototype.constructor = Greeter;
    console.log('Log 4: ' + Greeting);
    function Greeting(greeting){
    } 
    console.log('Log 5: ' + Greeting);
    return Greeting;
})();

console.log('Log 6: '+Greeting);


var greeting = new Greeting("World");
alert(greeting.greet());

您会看到Greeting只是一个空函数,但以Greeter为原型。因此,new Greeting('World')创建了以下函数:

function Greeting(greeting){
}

包含greeting(未定义),constructor(函数)和greet(函数)的原型。反过来,Greeting.prototype.greet有这个定义:

Greeting.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

this.greeting在此上下文中未定义,因为this指的是Greeting.prototype.greet,而不是Greeter。因此,这些行:

var greeting = new Greeting("World");
alert(greeting.greet());

失败,因为greeting.greet()返回Hello,与未定义值连接。

答案 3 :(得分:1)

您在greet上下文中调用Greeting方法,该方法不具有greeting属性。

在你的情况下没有理由将代码包装在IIEF中,因为没有私有变量,所以(它有效):

var Greeter = function (message) {
    this.greeting = message;
};

Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

var Greeting = function (greeting){
    Greeter.call(this, greeting)
} 

Greeting.prototype = new Greeter();        

var greeting = new Greeting("World");
alert(greeting.greet());

答案 4 :(得分:0)

像这样更改Greeting类:

var Greeting = (function(){
    function Greeting(greeting){
        Greeter.apply(this, arguments);
    }
    Greeting.prototype = new Greeter();        
    Greeting.prototype.constructor = Greeter;
    Greeting.superClass = Greeter;

    return Greeting;
})();

或者如果要为所有继承模型创建通用解决方案,请执行以下操作:

var Greeting = (function(){
    var Greeting = function $SubClass(greeting){
        $SubClass.prototype.constructor.apply(this, arguments);
    }
    Greeting.prototype = new Greeter();        
    Greeting.prototype.constructor = Greeter;

    return Greeting;
})();

这一部分的重点:

var Greeting = function $SubClass(greeting){};

是直接将函数赋值给变量时,只能在函数上下文中基于其标签($ SubClass)访问函数。