44 道 JavaScript 難題(JavaScript Puzzlers!)

來源:互聯網
上載者:User

標籤:second   負數   ||   賦值   報錯   fixed   索引   eve   indexof   

JavaScript Puzzlers原文1. ["1", "2", "3"].map(parseInt)
答案:[1, NaN, NaN]解析:parseInt (val, radix) :兩個參數,val值,radix基數(就是多少進位轉換)     map 能傳進回呼函數 3參數 (element, index, array)     parseInt(‘1‘, 0);  //0代表10進位     parseInt(‘2‘, 1);  //沒有1進位,不合法     parseInt(‘3‘, 2);  //2進位根本不會有3鞏固:["1", "1", "11","5"].map(parseInt) //[1, NaN, 3, NaN]  
2. [typeof null, null instanceof Object]
答案:["object", false]解析:null代表Null 物件指標,所以typeof判斷成一個對象。可以說JS設計上的一個BUG     instanceof 實際上判斷的是對象上建構函式,null是空當然不可能有建構函式鞏固:null == undefined //true    null === undefined //flase
3. [ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]
答案:an error解析:Math.pow (x , y)  x 的 y 次冪的值     reduce(fn,total)     fn (total, currentValue, currentIndex, arr)          如果一個函數不傳初始值,數組第一個組預設為初始值.         [3,2,1].reduce(Math.pow)         Math.pow(3,2) //9         Math.pow(9,1) //9鞏固:[].reduce(Math.pow)       //空數組會報TypeError     [1].reduce(Math.pow)      //只有初始值就不會執行回呼函數,直接返回1     [].reduce(Math.pow,1)     //只有初始值就不會執行回呼函數,直接返回1     [2].reduce(Math.pow,3)    //傳入初始值,執行回呼函數,返回9
4.
 var val = ‘smtg‘; console.log(‘Value is ‘ + (val === ‘smtg‘) ? ‘Something‘ : ‘Nothing‘);

這段代碼的執行結果?

答案:Something解析:字串串連比三元運算有更高的優先順序      所以原題等價於 ‘Value is true‘ ? ‘Somthing‘ : ‘Nonthing‘      而不是 ‘Value   is‘ + (true ? ‘Something‘ : ‘Nonthing‘)鞏固:    0 || fn() && fn()   //0  ||短路 ,後邊不會執行啊    0 || 1 ? 2 : 3 ;    //2  那這個為什麼不會短路呢?一兩句話說不清,我總結了一篇文章

JavaScript運算子優先順序之謎

5.
var name = ‘World!‘;(function () {if (typeof name === ‘undefined‘) {    var name = ‘Jack‘;    console.log(‘Goodbye ‘ + name);} else {    console.log(‘Hello ‘ + name);}})();

這段代碼的執行結果?

答案:Goodbye Jack解析:(1)typeof時 name變數提升。 在函數內部之聲明未定義     (2)typeof優先順序高於===鞏固:    var str = ‘World!‘;       (function (name) {    if (typeof name === ‘undefined‘) {        var name = ‘Jack‘;        console.log(‘Goodbye ‘ + name);    } else {        console.log(‘Hello ‘ + name);    }    })(str);    答案:Hello World 因為name已經變成函數內局部變數
6.
var END = Math.pow(2, 53);var START = END - 100;var count = 0;for (var i = START; i <= END; i++) {    count++;}console.log(count);

這段代碼的執行結果?

答案:other ,不是101解析:js中可以表示的最大整數不是2的53次方,而是1.7976931348623157e+308。2的53次方不是js能表示的最大整數而應該是能正確計算且不失精度的最大整數,鞏固:     var END = 1234567635;     var START = END - 1024;     var c = count = 0;     for (var i = START; i <= END; i++) {        c = count++;     }     console.log(count);   //1025     console.log(c);       //1024
7.
var ary = [0,1,2];ary[10] = 10;ary.filter(function(x) { return x === undefined;}); 

這段代碼的執行結果?

答案:[]解析:filter() 不會對空數組進行檢測。會跳過那些空元素鞏固:      var ary = [0,1,2,undefined,undefined,undefined,null];      ary.filter(function(x) { return x === undefined;});      // [undefined, undefined, undefined] 
8.
var two   = 0.2var one   = 0.1var eight = 0.8var six   = 0.6[two - one == one, eight - six == two]

這段代碼的執行結果?

答案:[true, false]解析:IEEE 754標準中的浮點數並不能精確地表達小數鞏固:var two   = 0.2;     var one   = 0.1;     var eight = 0.8;     var six   = 0.6;     ( eight - six ).toFixed(4) == two      //true
9.
function showCase(value) {    switch(value) {    case ‘A‘:        console.log(‘Case A‘);        break;    case ‘B‘:        console.log(‘Case B‘);        break;    case undefined:        console.log(‘undefined‘);        break;    default:        console.log(‘Do not know!‘);    }}showCase(new String(‘A‘));

這段代碼的執行結果?

答案:Do not know!解析:switch判斷的是全等(===) ,new String(x)是個對象鞏固:var a =  new String(‘A‘) ;      a.__proto__     // String.prototype 執行個體的原型指向建構函式的原型對象
10.
function showCase2(value) {    switch(value) {    case ‘A‘:        console.log(‘Case A‘);        break;    case ‘B‘:        console.log(‘Case B‘);        break;    case undefined:        console.log(‘undefined‘);        break;    default:        console.log(‘Do not know!‘);    }}showCase2(String(‘A‘));

這段代碼的執行結果?

答案:Case A解析:String(‘A‘)就是返回一個字串鞏固: var a2 =  ‘A‘;      a2.__proto__                  // String.prototype       a1.__proto__ === a2.__proto__  // true 上一題的a.__proto__      那字串不是對象為啥也指向String.prototype?解析:b是基本類型的值,邏輯上不應該有原型和方法。為了便於操作,有一種特殊的參考型別(基本封裝類型)String。其實讀取時,後台會自動完成下面的操作:      var str = new String("A"); //建立執行個體      str.__proto__;             //調用指定屬性和方法      str = null;                //銷毀執行個體      所以 a1.__proto__ === a2.__proto__      但注意基本封裝類型特殊就在於它對象(str)的生命週期,只存在於一行代碼(a1.__proto__ === a2.__proto__)的執行瞬間。      這也就解釋了為啥字串也能操作屬性和方法但不能添加。基本封裝類型有三個(String,Number,Boolean)     (詳情請看《js高程》 5.6基本包類型 P119)
11.
function isOdd(num) {    return num % 2 == 1;}function isEven(num) {    return num % 2 == 0;}function isSane(num) {    return isEven(num) || isOdd(num);}var values = [7, 4, ‘13‘, -9, Infinity];values.map(isSane);

這段代碼的執行結果?

答案:[true, true, true, false, false]解析:%如果不是數值會調用Number()去轉化     ‘13‘ % 2       // 1      Infinity % 2  //NaN  Infinity 是無窮大      -9 % 2        // -1鞏固: 9 % -2        // 1   餘數的加號或減號隨第一個運算元
12.
parseInt(3, 8)parseInt(3, 2)parseInt(3, 0)

這段代碼的執行結果?

答案:3  NaN  3解析:2進位不可能有3
13.
Array.isArray( Array.prototype )

這段代碼的執行結果?

答案:true解析:Array.prototype是一個數組     數組的原型是數組,對象的原型是對象,函數的原型是函數
14.
var a = [0];if ([0]) {  console.log(a == true);} else {  console.log("wut");}

這段代碼的執行結果?

答案:false解析:[0]的boolean值是true鞏固:a[0] 的boolean是 false
15.[]==[]
答案:false解析:兩個參考型別, ==比較的是引用地址鞏固:[]== ![]      (1)! 的優先順序高於== ,右邊運算結果等於 false     (2)一個參考型別和一個值去比較 把參考型別轉化成實值型別,左邊0     (3)所以 0 == false  答案是true
16.
‘5‘ + 3‘5‘ - 3

這段代碼的執行結果?

答案:53  2解析:加號有拼接功能,減號就是邏輯運算鞏固:typeof (+"1")   // "number" 對非數值+—常被用來做類型轉換相當於Number()
17. 1 + - + + + - + 1
答案:2解析:+-又是一元加和減操作符號,就是數學裡的加號或減號。負負得正哈。 鞏固: 一元運算子還有一個常用的用法就是將自執行函數的function從函式宣告變成運算式。      常用的有 + - ~ ! void      + function () { }      - function () { }      ~ function () { }      void function () { }
18.
var ary = Array(3);ary[0]=2ary.map(function(elem) { return ‘1‘; });

這段代碼的執行結果?

答案:["1", empty × 2]解析:如過沒有值,map會跳過不會執行回呼函數
19.
function sidEffecting(ary) {  ary[0] = ary[2];}function bar(a,b,c) {  c = 10  sidEffecting(arguments);  return a + b + c;}bar(1,1,1) 

這段代碼的執行結果?

答案:21, 解析:arguments會和函數參數綁定。鞏固:但如果es6付給初始值則無法修改      function sidEffecting(ary) {        ary[0] = ary[2];      }      function bar(a=1,b,c) {        c = 10        sidEffecting(arguments);        return a + b + c;    }       bar(1,1,1)       //12
20.
var a = 111111111111111110000,b = 1111;a + b;

這段代碼的執行結果?

答案:11111111111111111000解析:在JavaScript中number類型在JavaScript中以64位(8byte)來儲存。這64位中有符號位1位、指數位11位、實數位52位。2的53次方時,是最大值。其值為:9007199254740992(0x20000000000000)。超過這個值的話,運算的結果就會不對.
21.
var x = [].reverse;x();

這段代碼的執行結果?

答案:window解析:但在chrome上執行報錯,沒太懂
22.Number.MIN_VALUE > 0
答案:true解析:MIN_VALUE 屬性是 JavaScript 中可表示的最小的數(接近 0 ,但不是負數)。它的近似值為 5 x 10-324。
23.[1 < 2 < 3, 3 < 2 < 1]
答案:[true,true]解析: 1 < 2    =>  true;      true < 3 =>  1 < 3 => true;            3 < 2     => false;      false < 1 => 0 < 1 => true;
24. 2 == [[[2]]]
答案:true解析:值和參考型別去比較,把參考型別轉話成實值型別     [[[2]]])//2鞏固:++[[]][+[]]+[+[]] //"10"     (1)(++([[]][+[]])) + [+[]]  //這步看不懂看4題下面的文章,就是運算子權重判斷     (2)(++([[]][0])) + [0]      // 16題中我們講過+用來做類型轉換Number([]) ===0     (3)+([] + 1) + [0]            //[[]]數組的第0項就是[],++代表自增+1       *******  注意這一步不是 (++[]) + [0] 這樣是錯誤的   **********     (4)+([] + 1) + [0]           // 前面+將"1"轉成數字1 後邊,+是拼接 "0" 所以是字串"10"      這題的詳細解釋在下面的連結中。高票答案解釋的非常贊,推薦閱讀
鞏固題詳細解釋在stackoverflow25.
3.toString()3..toString()3...toString()

這段代碼的執行結果?

答案:error, "3", error解析:因為在 js 中 1.1, 1., .1 都是合法的數字. 那麼在解析 3.toString 的時候這個 . 到底是屬於這個數字還是函數調用呢? 只能是數字, 因為3.合法啊!
26.
(function(){  var x = y = 1;})();console.log(y);console.log(x);

這段代碼的執行結果?

答案:1, error解析:y 被賦值成全域變數,等價於     y = 1 ;     var x = y;
27.
var a = /123/,b = /123/;a == ba === b

這段代碼的執行結果?

答案:false, false解析:正則是對象,參考型別,相等(==)和全等(===)都是比較引用地址
28.
var a = [1, 2, 3],b = [1, 2, 3],c = [1, 2, 4]a ==  ba === ba >   ca <   c

這段代碼的執行結果?

答案:false, false, false, true解析:相等(==)和全等(===)還是比較引用地址     參考型別間比較大小是按照字典序比較,就是先比第一項誰大,相同再去比第二項。
29.
var a = {}, b = Object.prototype;[a.prototype === b, Object.getPrototypeOf(a) === b]    

這段代碼的執行結果?

答案:false, true解析:Object 的執行個體是 a,a上並沒有prototype屬性     a的__poroto__ 指向的是Object.prototype,也就是Object.getPrototypeOf(a)。a的原型對象是b
30.
function f() {}var a = f.prototype, b = Object.getPrototypeOf(f);a === b         

這段代碼的執行結果?

答案:false解析:a是建構函式f的原型 : {constructor: ?}     b是執行個體f的原型對象 : ? () { [native code] }
31.
function foo() { }var oldName = foo.name;foo.name = "bar";[oldName, foo.name]     

這段代碼的執行結果?

答案:["foo", "foo"]解析:函數的名字不可變.
32."1 2 3".replace(/\d/g, parseInt)
答案:"1 NaN 3"解析:replace() 回呼函數的四個參數:      1、匹配項        2、與模式中的子運算式匹配的字串        3、出現的位置        4、stringObject 本身 。如果沒有與子運算式匹配的項,第二參數為出現的位置.所以第一個參數是匹配項,第二個參數是位置 parseInt(‘1‘, 0) parseInt(‘2‘, 2)  //2進位中不可能有2 parseInt(‘3‘, 4)鞏固:   "And the %1".replace(/%([1-8])/g,function(match,a , b ,d){      console.log(match +"  "+ a + " "+ b +" "+d )    });   //%1  1 8 And the %1 
33.
function f() {}var parent = Object.getPrototypeOf(f);f.name // ?parent.name // ?typeof eval(f.name) // ?typeof eval(parent.name) //  ?  

這段代碼的執行結果?

答案:"f", "Empty", "function", error解析:f的函數名就是f     parent是f原型對象的名字為"" ,     先計算eval(f.name) 為 f,f的資料類型是function     eval(parent.name) 為undefined, "undefined"
34.
var lowerCaseOnly =  /^[a-z]+$/;lowerCaseOnly.test(null), lowerCaseOnly.test()]

這段代碼的執行結果?

答案:[true, true]解析:這裡 test 函數會將參數轉為字串. ‘nul‘, ‘undefined‘ 自然都是全小寫了
35.[,,,].join(",")
答案:",,"解析:因為javascript 在定義數組的時候允許最後一個元素後跟一個,     所以這個數組長度是3,鞏固: [,,1,].join(".").length //  3 
36.
var a = {class: "Animal", name: ‘Fido‘};a.class   

這段代碼的執行結果?

答案:other解析:這取決於瀏覽器。類是一個保留字,但是它被Chrome、Firefox和Opera接受為屬性名稱。在另一方面,每個人都會接受大多數其他保留詞(int,私人,拋出等)作為變數名,而類是VordBoint。
37.var a = new Date("epoch")
答案:other解析:您得到“無效日期”,這是一個實際的日期對象(一個日期的日期為true)。但無效。這是因為時間內部保持為一個數字,在這種情況下,它是NA。      在chrome上是undefined       正確的是格式是var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);
38.
var a = Function.length,b = new Function().lengtha === b

這段代碼的執行結果?

答案:false解析:首先new在函數帶()時運算優先順序和.一樣所以從左向右執行     new Function() 的函數長度為0鞏固:function fn () {         var a = 1;      }      console.log(fn.length)       //0 fn和new Function()一樣
39.
var a = Date(0);var b = new Date(0);var c = new Date();[a === b, b === c, a === c]

這段代碼的執行結果?

答案:[false, false, false]解析:當日期被作為建構函式調用時,它返回一個相對於劃時代的對象(JAN 01 1970)。當參數丟失時,它返回當前日期。當它作為函數調用時,它返回目前時間的字串表示形式。a是字串   a === b // 資料類型都不同,肯定是falseb是對象     b === c // 參考型別,比的是引用地址c也是對象   a === c // 資料類型都不同,肯定是false鞏固:  var a = Date(2018);       var b = Date(2001);       [a ===b ]       //[true] Date() 方法獲得當日的日期,作為函數調用不需要,返回的同一個字串       "Tue Jun 12 2018 14:36:24 GMT+0800 (CST)" 當然如果a,b執行時間相差1秒則為false
40.
var min = Math.min(), max = Math.max()min < max

這段代碼的執行結果?

答案:false解析: Math.min 不傳參數返回 Infinity, Math.max 不傳參數返回 -Infinity       無限集合之間不能比較大小。鞏固:Number.MAX_VALUE  > Number.MIN_VALUE  //true
41.
function captureOne(re, str) {  var match = re.exec(str);  return match && match[1];}var numRe  = /num=(\d+)/ig,    wordRe = /word=(\w+)/i,    a1 = captureOne(numRe,  "num=1"),    a2 = captureOne(wordRe, "word=1"),    a3 = captureOne(numRe,  "NUM=2"),    a4 = captureOne(wordRe,  "WORD=2");[a1 === a2, a3 === a4]

這段代碼的執行結果?

答案:[true, false]解析: /g有一個屬性叫lastIndex,每次匹配如果沒有匹配到,它將重設為0,如果匹配到了,他將記錄匹配的位置。我們看一個簡單的例子吧。        var numRe  = /num=(\d)/g;         numRe.test("num=1abcwewe") //true         numRe.lastIndex            //5     匹配到num=1後在5的索引位置         numRe.exec("num=1")        //fales 這次要從5的索引位置,開始匹配         numRe.lastIndex            //0     上一次匹配失敗了numRe.lastIndex重製為0
42.
var a = new Date("2014-03-19"),b = new Date(2014, 03, 19);[a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]

這段代碼的執行結果?

答案:[false, false]解析: var a = new Date("2014-03-19")    //能夠識別這樣的字串,返回想要的日期      Wed Mar 19 2014 08:00:00 GMT+0800 (CST)      b = new Date(2014, 03, 19);       //參數要按照索引來      Sat Apr 19 2014 00:00:00 GMT+0800 (CST)      月是從0索引,日期是從1       getDay()是擷取星期幾      getMonth()是擷取月份所以都不同鞏固: [a.getDate() === b.getDate()] //true
43.
 if (‘http://giftwrapped.com/picture.jpg‘.match(‘.gif‘)) {    ‘a gif file‘  } else {    ‘not a gif file‘  }

這段代碼的執行結果?

答案:‘a gif file‘解析: String.prototype.match 接受一個正則, 如果不是, 按照 new RegExp(obj) 轉化. 所以 . 並不會轉義 。 那麼 /gif 就匹配了 /.gif/鞏固: if (‘http://giftwrapped.com/picture.jpg‘.indexOf(‘.gif‘)) {        ‘a gif file‘      } else {        ‘not a gif file‘      }      //‘a gif file‘ 同樣的道理
44.
function foo(a) {  var a;  return a;}function bar(a) {    var a = ‘bye‘;    return a;}[foo(‘hello‘), bar(‘hello‘)]

這段代碼的執行結果?

答案:["hello", "bye"]解析:最後一題很簡單吧,變數聲明
 
17點
連結:https://juejin.im/post/5b1f899fe51d4506c60e46ee
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

44 道 JavaScript 難題(JavaScript Puzzlers!)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.