這是在網上看到的一道面試題 嗯 考察的知識點挺多 其他的就不多說了 我用我的理解與解題方式來解答這道題 1.首先是變數提升 變數提升包括var 聲明的變數和fucntion 聲明 舉個例子 1.var a=4; 2.function test(){ console.log(456); }; 函數變數 ...
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); }
這是在網上看到的一道面試題 嗯 考察的知識點挺多 其他的就不多說了
我用我的理解與解題方式來解答這道題
1.首先是變數提升
變數提升包括var 聲明的變數和fucntion 聲明
舉個例子
1.var a=4;
2.function test(){
console.log(456);
};
函數變數聲明會先於普通變數之前,並且不會被後面的同名覆蓋
但是會被後面的同名賦值覆蓋!
就是 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 |
從左到右 |
… , … |