JS 原型 ─ 为什么 'undefined'?

JS prototype ─ why 'undefined'?

我有一个非常简单的代码(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。但是什么是 unexpected,第一个警报输出 'undefined'。 为什么?


更新 特别是 GURU。如果你设置减号,请解释原因。谢谢。


UPD 2. 我只是没有在第一个 Fnc.prototype.fooz 中设置 return (在重新定义时)。是的,非常幼稚的错误。

在第一个 alert(fa.fooz()); 期间 Fnc.prototype.fooz 没有 returning 任何东西。所以默认情况下,一个函数将 return undefined,不是所有的时间,但在我们的例子中它会 return undefined。后来,Fnc.prototype.fooz 被分配了新功能,它是 returning 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. 
};

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

您对 Func.prototype.fooz 的第一个定义首先重新定义了它自己,然后 return 未定义。你的重新定义 return 是什么东西。

在 JavaScript 中没有 return 大多数函数 return 未定义。使用 new 调用的函数除外。

It outputs into console as expected, 1,2,7. But what is unexpected, that the first alert outputs 'undefined'. But why?!

当您在 Fnc.prototype.fooz 中重新定义 Fnc.prototype.fooz 时,它替换了之前未返回任何内容(意味着返回 undefined)的 Fnc.prototype.fooz 的定义。

请注意,即使您重新定义它,函数执行 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,因为先前的定义已被覆盖。