當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
javascript谜题
生活随笔
收集整理的這篇文章主要介紹了
javascript谜题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? | 測試一if(!("a"?in?window))?{????var?a?=?1; } alert(a); 測試二 var?a?=?1,????b?=?function?a(x)?{ ????????x?&&?a(--x); ????}; alert(a); 測試三 function?a(x)?{????return?x?*?2; } var?a; alert(a); 測試四 function?b(x,?y,?a)?{????arguments[2]?=?10; ????alert(a); } b(1,?2,?3); 測試五 function?a()?{????alert(this); } a.call(null); ? ? ? ? ? ----------------------------------------------------------------- 答案分水嶺 ------------------------------------------------------------------ ? ? ? ? 答案: 1.?undefined2.?1 3.?function?a(x)?{?return?x?*?2;?} 4.?10 5.?window ? 講解: 第一題 if?(!("a"?in?window))?{????var?a?=?1; } alert(a); 這段代碼用語言描述就是"如果window沒有屬性a,那么定義a等于1".?也許有人就會認為結果是1了.但測試 才會發現彈出的是undefined.這是問什么呢? 這個問題考察以下兩點: 1)?所有的全局變量都是window的屬性.?var?a?=?1實際上相當于window.a?=?1.?所以你可以使用 "variable-name"?in?window來檢測一個全局變量是否被定義. 2)?所有被var的變量聲明?都要被提到作用域的頂部.考慮一個簡單的例子: alert("a"?in?window); var?a; 這個結果會彈出true;盡管變量定義在后面.?這是因為javascript引擎首先掃描定義的變量并把他的作用域提到頂部.?所以上面的代碼近似于這樣: var?a; alert("a"?in?window); 讀這段代碼,你就會更清楚為什么彈出的是true. 3)?你需要知道咱們測試例子?當變量作用域定義并提前了.但卻并沒有初始化.下面這句是定義變量并初始化 var?a?=?1; 你可以分開看定義變量和初始化: var?a;?//定義 a?=?1;?初始化 但JS引擎解析一個合并的var?a?=?1;是自動將其分離的.所以可以將定義被提前.但為什么值不提前呢??因為值會影響到后面的值而導致不可預知的結果出現. 所以.知道了上面這三點.重新思考下剛才的例子.其實就可以分解為 var?a; if?(!("a"?in?window))?{ ????a?=?1; } alert(a); 這樣就可以看出if檢測的時候a已經被定義了?默認為undefined所以分支不會走?最后彈出了'undefined' 第二題 var?a?=?1,????b?=?function?a(x)?{ ????????x?&&?a(--x); ????}; alert(a); 這個例子看上去要比實際復雜.這個結果顯示1.?主要是看哪個a最后被實例化了.這個問題也需要搞清3個知識點. 1)?就是定義的變量作用域被提前.這個在實例1已經講解了. 2)?就是所有的function定義的作用域也隨著var變量定義一起提前.但必須搞清楚的是.一個函數定義是這樣子的: function?functionName(arg1,?arg2){ ????//function?body } 這個要區別于函數表達式.函數表達式是賦予一個變量,是這樣的: var?functionName?=?function(arg1,?arg2){ ????//function?body }; 要搞清楚的是.函數表達式不會作用域提前.這樣應該意識到.如果將value初始化值,從代碼的一段移到另一段會產生影響. 3)?就是要必須理解記住函數聲明重寫的是變量聲明.但不是變量初始化.理解這句話考慮下面的例子 function?value(){ ????return?1; } var?value; alert(typeof?value);????//"function" 盡快變量聲明在函數聲明的后面.但函數聲明會吧優先權讓給變量聲明.但是經過變量初始化你將會得到不同的結果 function?value(){ ????return?1; } var?value?=?1; alert(typeof?value);????//"number" 因為value?=?1變量賦值的時候又覆蓋了?函數聲明?所以變成了1 回歸到咱們的測試題?其實可以簡化成下面這樣: var?a?=?1, ????b?=?function(x)?{ ????????x?&&?b(--x); ????}; alert(a); 顯而易見?就是彈出1 第三題 function?a(x)?{????return?x?*?2; } var?a; alert(a); 如果理解了前面的兩個實例那么這個就很容易理解了.var?a;作用域被提前?然后函數a將其覆蓋.?由于沒有a變量賦值,?所以最后彈出了整個函數的source 第四題 function?b(x,?y,?a)?{????arguments[2]?=?10; ????alert(a); } b(1,?2,?3); 這個例子在所有瀏覽器里都顯示10. 原因.首先放上ECMA對arguments的說明. ECMA-262,?3rd?Edition,?section?10.1.8?says?about?an?arguments?object: For?each?non-negative?integer,?arg,?less?than?the?value?of?the?length?property,?a?property?is?created?with?name?ToString(arg)?and?property?attributes?{?DontEnum?}.?The?initial?value?of?this?property?is?the?value?of?the?corresponding?actual?parameter?supplied?by?the?caller.?The?first?actual?parameter?value?corresponds?to?arg?=?0,?the?second?to?arg?=?1,?and?so?on.?In?the?case?when?arg?is?less?than?the?number?of?formal?parameters?for?the?Function?object,?this?property?shares?its?value?with?the?corresponding?property?of?the?activation?object.?This?means?that?changing?this?property?changes?the?corresponding?property?of?the?activation?object?and?vice?versa. 尤其最后這一句 This?means?that?changing?this?property?changes?the?corresponding?property?of?the?activation?object?and?vice?versa. 當arguments的屬性值改變那么活動對象的對應屬性也跟著變.反之亦然. 簡而言之就是arguments的屬性和相對性對象的屬性?是值共享的?兩者總是保持著相同的值. 所以由于arguments[2]?=?10了?所以對應的活動對象屬性也為10. 第五題 function?a()?{????alert(this); } a.call(null); 這個其實理解起來沒那么難.我們需要了解兩個知識點. 1)?應該理解this的值是怎么確定的.當一個對象的方法被執行.this就指向該方法的擁有者這個對象.如 var?object?=?{ ????method:?function()?{ ????????alert(this?===?object);????//true ????} } object.method();? 在上面的代碼里.當object.method()被執行時.this最終指向object.在全局環境里this指向window(當然如果非瀏覽器對象就指向默認的宿主).所以當一個函數不屬于一個對象的屬性是?那么this就等于window function?method()?{ ????alert(this?===?window);????//true } method();? 上面的this就指向了全局的對象?window. 2)?有了(1)的知識做基礎.我們再需要的就是知道第二個重要的點.call做了什么.call()方法執行函數.比如另一個對象的方法.?這個方法的this將被call的第一個函數代替,然后其余的參數就按順序傳入到那個方法中. function?method()?{ ????alert(this?===?window); } method();????//true method.call(document);???//false 此時call是method內部的this指向了document所以返回false. **An?interesting?part?of?ECMA-262,?3rd?edition?describes?what?should?happen?when?null?is?passed?in?as?the?first?argument?to?call(): If?thisArg?is?null?or?undefined,?the?called?function?is?passed?the?global?object?as?the?this?value.?Otherwise,?the?called?function?is?passed?ToObject(thisArg)?as?the?this?value. 所以call(或者apply)如果傳入null.將默認為全局對象.即瀏覽器的window或者其它的宿主環境.所以例子可以改寫為: function?a()?{ ????alert(this); } a.call(window); 這樣結果就會顯示window. |
轉載于:https://www.cnblogs.com/linpengfeixgu/articles/1658380.html
總結
以上是生活随笔為你收集整理的javascript谜题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 易度甘特图的功能介绍和开发手册
- 下一篇: javascript装饰者模式