JS原型─为什么' undefined'?

时间:2016-03-04 13:04:56

标签: javascript runtime prototype

我有一个非常简单的代码(http://plnkr.co/edit/voHWdFfwu7TUreyjsRiU?p=preview):

function Fnc(){}
Fnc.prototype.fooz = function(){
    var i=0;
    Fnc.prototype.fooz = function(){
        ++i;
        console.log('i: ', i);
        return i;
    };
    Fnc.prototype.fooz();
};


window.onload=function(){
    var fa = new Fnc();
    alert(fa.fooz()); // undefined!
    alert(fa.fooz()); // 2
    alert(fa.fooz() + fa.fooz()); // 7
};

按预期输出到控制台,1,2,7。但意外是什么,第一个警报输出' undefined'。 为什么呢?

UPD 特别是对于ie GURU 。如果你设置减号,PLZ,解释原因。谢谢。

UPD 2.我只是没有在第一个Fnc.prototype.fooz中设置返回(当它重新加工时)。是的,非常天真的错误。

3 个答案:

答案 0 :(得分:2)

您对Func.prototype.fooz的第一个定义首先重新定义自身,然后返回undefined。你的重新定义会返回一些东西。

在没有返回的JavaScript中,大多数函数返回undefined。例外是使用new调用的函数。

答案 1 :(得分:1)

在第一个alert(fa.fooz());期间Fnc.prototype.fooz没有返回任何内容。因此,默认情况下,函数将返回undefined,而不是所有时间,但在我们的情况下,它将返回undefined。稍后,Fnc.prototype.fooz被赋予了新函数,并返回i值。这就是它给出预期结果的原因。

Fnc.prototype.fooz = function(){
    var i=0;
    Fnc.prototype.fooz = function(){
        ++i;
        console.log('i: ', i);
        return i;
    };
    Fnc.prototype.fooz();  // This is not retuning anything 
};

如果您想获得所需的结果,只需更改下面的代码,

Fnc.prototype.fooz = function(){
    var i=0;
    Fnc.prototype.fooz = function(){
        ++i;
        console.log('i: ', i);
        return i;
    };
    return Fnc.prototype.fooz();  // add a return here. 
};

尝试语言将指导您探索它。但是不要在实时项目中修改同一函数内的原型,因为它会导致不良结果。

答案 2 :(得分:1)

  

按预期输出到控制台,1,2,7。但是出乎意料的是,   第一个警报输出'undefined'。但为什么呢?!

当你在Fnc.prototype.fooz内重新定义Fnc.prototype.fooz时,它取代了之前没有返回任何内容的Fnc.prototype.fooz定义(意味着返回undefined)。

请注意,即使您重新定义了函数执行Fnc.prototype.fooz();,也可以先完成。

例如,如果我在函数执行之前添加console.log

function Fnc(){}
Fnc.prototype.fooz = function(){
    var i=0;
    Fnc.prototype.fooz = function(){
        ++i;
        console.log('i: ', i); //second print when executed first time
        return i;
    };
    console.log(Fnc.prototype.fooz); //this line will be printed first
    Fnc.prototype.fooz();
};

下次只打开新定义(即console.log('i: ', i);)内的console.log,因为之前的定义已被覆盖。