在這裏作了套題:賢心 而後錯的……不忍直視。 還有一篇很好的介紹函數表達式的文章: (http://www.cnblogs.com/TomXu/archive/2011/12/29/2290308.html)javascript
typeof操做符返回一個字符串,表示未經求值的操做數(unevaluated operand)的類型。 typeof 可能的返回值以下:html
**null ** 注意這個特殊的 typeof null === object.java
常見的面試題中涉及到typeof面試
(function(){ return typeof arguments; })();
返回值爲:object
arguments是對象,不是真正的數組,它是一個僞數組,是可使用方括號和整數索引的元素。一般利用Array的原型方式將其轉換爲數組。 Array.prototype.slice.call(arguments);express
var f = function g(){ return 23; }; typeof g();
Uncaught ReferenceError: g is not defined(…)
由於function g(){ return 23; }是函數表達式,事實上g只是一個名字,不是函數聲明。函數其實是綁定到變量f,而不是g。 指定的函數標識符:g通常的用途是:使堆棧跟蹤更加清晰,可使用匿名函數遞歸調用其自身,而不須要使用argument.callee.(注意 ES5 嚴格模式中禁用)數組
var y = 1, x = y = typeof x; x;
undefined
重寫上述代碼以下:函數
var y = 1; y = typeof x; var x = y; x;
當執行y = typeof x時,x 尚未被定義,因此y成爲字符串」undefined」,而後被分配到x。this
(function f(f){ return typeof f(); })(function(){ return 1; });
「number」
分解以下: 第一部分lua
var baz = function(){ return 1; };
第二部分prototype
(function f(f){ return typeof f(); })(baz);
在這裏,函數f接受一個參數是另外一個函數,f函數內部執行這個實參函數而且返回類型 不管是從調用該函數返回,即便參數名稱f與函數名衝突,函數接受自己做爲本身的參數,而後調用,此時就看誰更具備更高的優先級了,顯然,參數的優先級更高,因此實際執行的是
return typeof 1。
var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)(); 「undefined」
繼續改寫一下:
var foo = { bar: function(){ return this.baz; }, baz: 1 } f = foo.bar; typeof f();
把foo.bar存儲給f而後調用,因此this在foo.bar引用的是全局對象,因此就沒有baz屬性了 換句話說foo.bar執行的時候上下文是 foo,可是當 把 foo.bar 賦值給 f 的時候,f 的上下文環境是 window ,是沒有 baz 的,因此是 」undefined」 題目五
var f = (function f(){ return "1"; }, function g(){ return 2; })(); typeof f; 「number」
逗號操做符的使用能夠很混淆,但這段說明它的行爲:
var x = (1, 2, 3); x;
x的值是3,這代表,當你有一系列的組合在一塊兒,並由逗號分隔的表達式,它們從左到右進行計算,但只有最後一個表達式的結果保存。因爲一樣的緣由,這個問題能夠改寫爲減小混亂:
var f = (function g(){ return 2; })(); typeof f;
關於逗號表達式: 原文: http://www.2ality.com/2012/09/expressions-vs-statements.html 譯文: http://www.cnblogs.com/ziyunfei/archive/2012/09/16/2687589.html
var x = 1; if (function f(){}) { x += typeof f; } x; 「1undefined」
這裏有個難點 if 中的 function f(){} 要如何處理? 函數聲明的實際規則以下: 函數聲明只能出如今程序或函數體內。從句法上講,它們 不能出如今Block(塊)({ … })中,例如不能出如今 if、while 或 for 語句中。由於 Block(塊) 中只能包含Statement語句, 而不能包含函數聲明這樣的源元素。另外一方面,仔細看一看規則也會發現,惟一可能讓表達式出如今Block(塊)中情形,就是讓它做爲表達式語句的一部分。可是,規範明確規定了表達式語句不能以關鍵字function開頭。而這實際上就是說,函數表達式一樣也不能出如今Statement語句或Block(塊)中(由於Block(塊)就是由Statement語句構成的)。 假設代碼咱們不妨變一下:
var x = 1; if (function(){}) { x += typeof f; } x; var x = 1; x += typeof f; x;
f在這了沒有被定義,因此typeof f 是字符串」undefined」 ,字符與數字相加結果也是一個字符串, 因此最後的x就是」1undefined」了
(function f(){ function f(){ return 1; } return f(); function f(){ return 2; } })(); 2
若是是一直看下來的話,這個題目應該是比較簡單 簡單的來講在執行return以前,函數聲明會在任何表達式被解析和求值以前先被解析和求值。 即便你的聲明在代碼的最後一行,它也會在同做用域內第一個表達式以前被解析/求值, 參考以下例子,函數fn是在alert以後聲明的,可是在alert執行的時候,fn已經有定義了
alert(fn()); function fn() { return 'Hello world!'; }
因此題目中函數提高了兩次,第二次把第一次覆蓋了, 因此 return 後面的 f 是 return 語句的下一條語句聲明的函數 f 。 注意自執行函數 (function f (){})(); 中的 f 並無函數提高效果,它是表達式
function f(){ return f; } new f() instanceof f; false
怎樣去理解?
new f()
首先這個操做會建立一個新對象並調用構造函數函數這一新的對象做爲它的當前上下文對象 簡單的說
new f();
依稀記得高級程序設計裏面是這麼說的:
默認若是沒有覆蓋這個空對象的話,返回this var a = new Object; a instanceof Object 爲 true 咱們在看 f() 返回了 return f; 那麼也就是說這個新的對象是是自身,構造函數自己在 new 的過程當中會返回一個表示該對象的實例。 可是函數的返回值覆蓋了這個實例,這個new 就形同虛設 果f的形式爲 function f(){return this}或function f(){}就不同
var a = new f(); a instanceof f // false
值得注意的是 instanceof 檢測的是原型
var x = [typeof x, typeof y][1]; typeof typeof x;
這題目比較簡單,注意下返回類型便可 x = [,][1]; 即 x = typeof y = ‘undefind’. typeof 返回的是string類型就能夠了 typeof typeof必然就是’string’了.
function(foo){ return typeof foo.bar; })({ foo: { bar: 1 } });
「undefined」 又是一個噁心的題目,純文字遊戲,你們看仔細看 先分解一下
var baz = { foo: { bar: 1 } }; (function(foo){ return typeof foo.bar; })(baz);
去掉函數關聯
var baz = { foo: { bar: 1 } }; var foo = baz; typeof foo.bar;
最後,經過替代咱們除去中間變量foo
var baz = { foo: { bar: 1 } }; typeof baz.bar;
因此如今就很清晰了,屬性中沒有定義baz;它被定義爲baz.foo上了,因此結果是:」undefined」