06.14 44 道 JavaScript 難題(JavaScript Puzzlers!)

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代表空對象指針,所以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 && null === 0 //0 === 優先級高於 &&

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時var 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.2
var one = 0.1
var eight = 0.8
var 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!
解析:new String(x)是個對象
鞏固:下一題

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')就是返回一個字符串

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
解析:加號有拼接功能,減號就是邏輯運算

17. 1 + - + + + - + 1

答案:2
解析:+-又代表正負號, 負負得正。

18.

var ary = Array(3);
ary[0]=2
ary.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

25.

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 == b
a === b

這段代碼的執行結果?

答案:false, false
解析:正則是對象,引用類型,相等(==)和全等(===)都是比較引用地址

28.

var a = [1, 2, 3],
b = [1, 2, 3],
c = [1, 2, 4]
a == b
a === b
a > c
a < 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().length
a === 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 // 數據類型都不同,肯定是false
b是對象 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!)


分享到:


相關文章: