一道面試題 包含了new的細節 和運算符的優先級 還有屬性訪問機制

 function Foo() {
getName = function () { alert(1); } return this; }
Foo.getName = function () { alert(2); } Foo.prototype.getName = function () { alert(3); } var getName = function () { alert(4); } function getName () { alert(5); }

  這是在網上看到的一道面試題  嗯 考察的知識點挺多  其餘的就很少說了html

  我用個人理解與解題方式來解答這道題面試

  1.首先是變量提高ide

   變量提高包括var 聲明的變量和fucntion 聲明函數

   舉個例子ui

      1.var a=4; this

      2.function test(){spa

       console.log(456);prototype

     };code

     

   函數變量聲明會先於普通變量以前,而且不會被後面的同名覆蓋htm

   可是會被後面的同名賦值覆蓋!

   就是 function a(){};

       var a;

       這樣不會覆蓋函數a

       可是若是 var a=4;

       函數a就會被覆蓋

 

      接下來從第一個開始分析

         Foo.getName();

首先變量提高以後是這個樣子滴

//變量提高

          第一題function Foo(){

                 getName = function () { alert(1); }//foo函數執行的時候 會覆蓋全局中的getName
                 return this;

                 /* 

                      new 運算符的時候會執行如下

                      var obj={};//建立一個空對象

                      將構造函數的做用域賦給新對象

                      這個新對象的內置原形指向構造函數的原形對象

                      obj.__proto__=Foo.prototype;

                      執行構造函數中的代碼

                      返回這個對象(若是顯示返回基本數據類型 無效 仍是會返回這個對象

                                  若是返回的是引用類型 那麼這個對象將沒用了)

                     

               */

              }

           //變量提高

          //2.function getName () { alert(5); }

         //變量提高

           3.var getName;


           4.Foo.getName = function () { alert(2); }
           5.Foo.prototype.getName = function () { alert(3); }
           6.getName = function () { alert(4); }

 

           以前的2 會被6覆蓋 因此2就能夠註釋掉了

 第二題 Foo.getName(); //彈出窗口值爲2 不用解釋了吧
第三題 getName();//彈出窗口值爲4
第四題 Foo().getName();

先執行Foo();
裏面的getName=function(){alert(1);} 會覆蓋全局做用域中的6
由於是在全局做用域下調用Foo函數 因此this就是window
window.getName(); //彈出窗口值爲6

第五題 new Foo.getName();

new (Foo.getName)(); //彈出窗口值爲2
笨想:確定不會是執行Foo.getName 以後才new 會報錯
優先級問題 .(成員訪問的優先級高於new 而且從左到右
因而就把Foo.getName這個函數當作構造函數執行
                            

第六題
new Foo().getName();
.運算符從左到右
new Foo(); 返回一個Foo類型的對象 {}
{}.getName();
找不到 而後去構造它的函數Foo的prototype上找
Foo.prototype.getName = function () { alert(3); }
因此結果 3


第七題
也是運算符優先級的問
new new Foo().getName(); 在這裏面.的優先級最高
 new ((new Foo()).getName)(); 
先執行.左 而後.右
先執行Foo(); 而後new 返回一個Foo類型的對象
而後獲得getName的函數體
而後當作構造函數執行 alert(3) 而後返回一個Foo.getName類型的對象


可能有些地方不是讓全部人懂
畢竟我也是一直菜鳥


// Foo.getName(); //2
// getName(); //4
// Foo().getName(); //1
// getName(); //1
// new Foo.getName();//2
// new Foo().getName();//3
// new (new Foo().getName)()//3;

優先級

運算類型

關聯性

運算符

20

圓括號

n/a

( … )

19

成員訪問

從左到右

… . …

需計算的成員訪問

從左到右

… [ … ]

new (帶參數列表)

n/a

new … ( … )

函數調用

從左到右

… ( … )

18

new (無參數列表)

從右到左

new …

17

後置遞增(運算符在後)

n/a

… ++

後置遞減(運算符在後)

n/a

… --

16

邏輯非

從右到左

! …

按位非

從右到左

~ …

一元加法

從右到左

+ …

一元減法

從右到左

- …

前置遞增

從右到左

++ …

前置遞減

從右到左

-- …

typeof

從右到左

typeof …

void

從右到左

void …

delete

從右到左

delete …

15

從右到左

… ** …

14

乘法

從左到右

… * …

除法

從左到右

… / …

取模

從左到右

… % …

13

加法

從左到右

… + …

減法

從左到右

… - …

12

按位左移

從左到右

… << …

按位右移

從左到右

… >> …

無符號右移

從左到右

… >>> …

11

小於

從左到右

… < …

小於等於

從左到右

… <= …

大於

從左到右

… > …

大於等於

從左到右

… >= …

in

從左到右

… in …

instanceof

從左到右

… instanceof …

10

等號

從左到右

… == …

非等號

從左到右

… != …

全等號

從左到右

… === …

非全等號

從左到右

… !== …

9

按位與

從左到右

… & …

8

按位異或

從左到右

… ^ …

7

按位或

從左到右

… | …

6

邏輯與

從左到右

… && …

5

邏輯或

從左到右

… || …

4

條件運算符

從右到左

… ? … : …

3

賦值

從右到左

… = …

… += …

… -= …

… *= …

… /= …

… %= …

… <<= …

… >>= …

… >>>= …

… &= …

… ^= …

… |= …

2

yield

從右到左

yield …

yield*

從右到左

yield* …

1

展開運算符

n/a

... …

0

逗號

從左到右

… , …

相關文章
相關標籤/搜索