js面接問題Foo.getNameの話

4042 ワード

まず声明します.この問題は面接の時の筆記試験問題の一つです.帰ってきたら、同じというのは偶然です.
原題:
 
 
  • function Foo() {
  • getName = function () {
  • console.log (1);
  • };
  • console.log('this is'+this)
  • return this;
  • }
  • Foo.getName = function () {
  • console.log (2);
  • };
  • Foo.prototype.getName = function () {
  • console.log('baidu' && 'google');
  • };
  • var getName = function () {
  • console.log (4);
  • };
  • function getName() {
  • console.log (5);
  • }
  •  
  • //
  • Foo.getName();
  • getName();
  • Foo().getName();
  • getName();
  • new Foo.getName();
  • new Foo().getName();
  • new new Foo().getName();
  •  
     
    まず結果を出力します.
     
     
  • Foo.getName(); // 2
  • getName(); // 4
  • Foo().getName(); // 1
  • getName(); // 1
  • new Foo.getName(); // 2
  • new Foo().getName(); // google
  • new new Foo().getName(); // google
  •  
    この問題に関する知識点は幅広くて、この問題を分析する能力があります.また、論理演算子、演算子の優先度、宣言変数と宣言関数の優先度、プロトタイプの継承、クローズド、カバーなどの知識点が必要です.
     
    これから始めましょう.
    まず各ブロックの関数を番号付けします.
     
     
  • // 1: , getName ( )
  • function Foo() {
  • getName = function () {
  • console.log (1);
  • };
  • return this;
  • }
  • // 2: getName
  • Foo.getName = function () {
  • console.log (2);
  • };
  • // 3: getName
  • Foo.prototype.getName = function () {
  • console.log('baidu' && 'google');
  • };
  • // 4:
  • var getName = function () {
  • console.log (4);
  • };
  • // 5: getName
  • function getName() {
  • console.log (5);
  • }
  • 各ブロック関数の意味は分かりましたよね.続いて実行文のコードを分析します.実行文の第一行:Foo.getName()           この文は何も言いたいことはないでしょう.コール方式2の関数コードブロックです.結果は「2」です.実行文2行目:get Name()           この実行文を単独で見ると、大域的な声明の関数として5つの「function getName(){}」がありますが、この複雑な文脈環境に置かれているなら、それは違っています.4つの方法があります.(お母さんとお嫁さんが水に落ちました.誰を助けましたか?nono、そんなに気にしていません.)定義された変数と声明の関数が重名になったらどうしますか?答え:いずれも事前解析を行います.関数宣言は変数宣言より先に行われますが、最終的には変数に上書きされます.so方式4は勝ちました.出力結果は「4」です.実行文の3行目:Foo().Natme()        この文には、実行順があります.まず、方式1の「Foo()」を実行して、結果は「this」であり、windowを指して、グローバルgetName(window.getName)ポインタが匿名関数を指して、「this.getName()」を実行します.実は、作りたてのグローバルgetNameが指す匿名関数を実行します.        この文は、1で実行されたグローバル変数getNameポインタが指す匿名関数です.なぜ実行されないのかという質問があります.4はすでに上書きされています.だから、結果は1.>>実行文の5行目:new Foo.getName()        まずは演算子優先です.自分で見た結果は「new Foo()」です. Foo()>>new Foo」は、まず演算方式2のFoo.getName()の結果を「2」とし、newのFooオブジェクトの例を示します.>>実行文6行目:new Foo().getName()        まずnew Foo()を実行して、結果として新しいインスタンスオブジェクトを生成し、Foo()というコンストラクタのgetName方法を継承したので、方式3の関数ブロックを実行します.続いて、他の知識点に関連します.論理演算子演算は、前者が本物であるならば、後者を実行します.そうでなければ、前者だけを実行します.前者が本当なら前者だけを実行しても後者は実行しなくてもいいです.結果は「google」です.実行文の7行目:new new Foo().getName()        まずnew Foo()を実行して、new Fooの例示的なオブジェクトになりました.getName()を実行してから、Fooの例示的なオブジェクトを実行します.getName()は、方式3の関数ブロックに戻ります.結果は「google」となり、最後にnew Fooのインスタンスオブジェクトを実行します.