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 … |
||
從右到左 |
void … |
||
從右到左 |
delete … |
||
15 |
從右到左 |
… ** … |
|
14 |
從左到右 |
… * … |
|
從左到右 |
… / … |
||
從左到右 |
… % … |
||
13 |
從左到右 |
… + … |
|
從左到右 |
… - … |
||
12 |
從左到右 |
… << … |
|
從左到右 |
… >> … |
||
從左到右 |
… >>> … |
||
11 |
從左到右 |
… < … |
|
從左到右 |
… <= … |
||
從左到右 |
… > … |
||
從左到右 |
… >= … |
||
從左到右 |
… in … |
||
從左到右 |
… instanceof … |
||
10 |
從左到右 |
… == … |
|
從左到右 |
… != … |
||
從左到右 |
… === … |
||
從左到右 |
… !== … |
||
9 |
從左到右 |
… & … |
|
8 |
從左到右 |
… ^ … |
|
7 |
從左到右 |
… | … |
|
6 |
從左到右 |
… && … |
|
5 |
從左到右 |
… || … |
|
4 |
從右到左 |
… ? … : … |
|
3 |
從右到左 |
… = … |
|
… += … |
|||
… -= … |
|||
… *= … |
|||
… /= … |
|||
… %= … |
|||
… <<= … |
|||
… >>= … |
|||
… >>>= … |
|||
… &= … |
|||
… ^= … |
|||
… |= … |
|||
2 |
從右到左 |
yield … |
|
從右到左 |
yield* … |
||
1 |
n/a |
... … |
|
0 |
從左到右 |
… , … |