新聞中心
前言
題目主要來自看到過的易錯題,還有經(jīng)典的44道 JavaScript Puzzlers!, stackoverflow 這上面有很多Questions不錯的,可以好好補一補基礎(chǔ)。

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的建平網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
. VS = 操作符優(yōu)先級
- let a = {n : 1};
- let b = a;
- a.x = a = {n: 2};
- console.log(a.x)
- console.log(b.x)
輸出是什么呢?
真的想明白了嗎?
- undefined
- { n : 2}
你真的了解作用域嗎
- var a = 0,
- b = 0;
- function A(a) {
- A = function (b) {
- console.log(a + b++)
- }
- console.log(a++)
- }
- A(1)
- A(2)
留給你們思考,我可是第一遍就做錯了(;′⌒`)
答案 1 4
可以好好想一想,你會茅塞頓開的。
類數(shù)組的length
- var obj = {
- "2" : 3,
- "3" : 4,
- "length" : 2,
- "splice" : Array.prototype.splice,
- "push" : Array.prototype.push
- }
- obj.push(1)
- obj.push(2)
- console.log(obj)
這段代碼的執(zhí)行結(jié)果?
- 答案:Object(4) [empty × 2, 1, 2, splice: ?, push: ?]
- 解釋就是第一次使用push,obj對象的push方法設(shè)置obj[2] = 1,obj.length++
- 解釋就是第一次使用push,obj對象的push方法設(shè)置obj[3] = 2,obj.length++
- 使用console.log()方法輸出的時候,因為obj上有l(wèi)ength屬性和splice方法,故將其作為數(shù)組輸出打印
- 打印時因為數(shù)組未設(shè)置下標為0和1的值,故打印的結(jié)果就是empty,主動獲取obj[0] = undefined
非匿名自執(zhí)行函數(shù),函數(shù)名只讀
- var b = 10;
- (function b(){
- // 'use strict'
- b = 20
- console.log(b)
- })()
輸出的結(jié)果是什么?
- Function b
- - 如標題一樣,非匿名自執(zhí)行函數(shù),函數(shù)名不可以修改,嚴格模式下會TypeError,
- - 非嚴格模式下,不報錯,修改也沒有用。
- - 查找變量b時,立即執(zhí)行函數(shù)會有內(nèi)部作用域,會先去查找是否有b變量的聲明,有的話,直接復(fù)制
- - 確實發(fā)現(xiàn)具名函數(shù)Function b(){} 所以就拿來做b的值
- - IIFE的函數(shù)內(nèi)部無法進行復(fù)制(類似于const)
非匿名自執(zhí)行函數(shù) II
- var b = 10;
- (function b(){
- // 'use strict'
- var b = 20
- console.log(window.b)
- console.log(b)
- })()
輸出是多少呢?
- 10
- 20
- // 訪問b變量的時候,發(fā)現(xiàn)var b = 20;在當(dāng)前作用域中找到了b變量,于是把b的值作為20
非匿名自執(zhí)行函數(shù) III
- var b = 10;
- (function b(){
- console.log(b)
- b = 5
- console.log(window.b)
- var b = 20
- console.log(b)
- })()
輸出的結(jié)果是多少呢?
這個問題應(yīng)該不難,就留給你們思考吧
變量提升
- var name = 'World!';
- (function () {
- if (typeof name === 'undefined') {
- var name = 'Jack';
- console.log('Goodbye ' + name);
- } else {
- console.log('Hello ' + name);
- }
- })();
在 JavaScript中, Fun 和 var 會被提升
相當(dāng)于
- var name = 'World!';
- (function () {
- var name;
- if (typeof name === 'undefined') {
- name = 'Jack';
- console.log('Goodbye ' + name);
- } else {
- console.log('Hello ' + name);
- }
- })();
鞏固一下:
- 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已經(jīng)變成函數(shù)內(nèi)局部變量
最大整數(shù)
- var END = Math.pow(2, 53);
- var START = END - 100;
- var count = 0;
- for (var i = START; i <= END; i++) {
- count++;
- }
- console.log(count);
一個知識點:Infinity
- 在 JS 里, Math.pow(2, 53) == 9007199254740992 是可以表示的最大值. 最大值加一還是最大值. 所以循環(huán)不會停.
稀疏數(shù)組與密數(shù)組
- var ary = [0,1,2];
- ary[10] = 10;
- ary.filter(function(x) { return x === undefined;});
執(zhí)行結(jié)果如何呢?
做這個題目,你需要了解稀疏數(shù)組和密集數(shù)組
- 譯 JavaScript中的稀疏數(shù)組與密集數(shù)組
- Array/filter
看過源碼的同學(xué)應(yīng)該知道,filter源碼中,會去判斷數(shù)組的這個索引值是不是數(shù)組的一個屬性,有興趣的同學(xué)可以看看我寫的這篇關(guān)于數(shù)組的:[干貨]從詳細操作js數(shù)組到淺析v8中array.js
- 0 in ary; => true
- 3 in ary; => false
- 10 in ary; => true
- 也就是說 從 3 - 9 都是沒有初始化的'坑'!, 這些索引并不存在與數(shù)組中. 在 array 的函數(shù)調(diào)用的時候是會跳過這些'坑'的.
所以答案就是[]
浮點運算
- var two = 0.2
- var one = 0.1
- var eight = 0.8
- var six = 0.6
- [two - one == one, eight - six == two]
你認為結(jié)果是多少呢?面試遇到這個問題,應(yīng)該怎么回答呢?
- [true,false]
可以看看這些文章:
- 探尋 JavaScript 精度問題以及解決方案
- 從0.1+0.2=0.30000000000000004再看JS中的Number類型
Switch
- 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'));
運行結(jié)果如何呢?
- switch 是嚴格比較, String 實例和 字符串不一樣.
- 答案自然是'Do not know'
- 所以一般情況下,寫switch語句,也建議寫default
String("A")
- 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'));
運行結(jié)果呢?
- 答案:Case A
- 解析:String('A')就是返回一個字符串
%運算符
- 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);
運行的結(jié)果如何呢?
- 答案:[true, true, true, false, false]
- 解析:%如果不是數(shù)值會調(diào)用Number()去轉(zhuǎn)化
- '13' % 2 // 1
- Infinity % 2 //NaN Infinity 是無窮大
- -9 % 2 // -1
- 鞏固:9 % -2 // 1 余數(shù)的正負號隨第一個操作數(shù)
數(shù)組的原型是什么
- Array.isArray( Array.prototype )
這段代碼的執(zhí)行結(jié)果?
- 答案:true
- 解析:Array.prototype是一個數(shù)組
- 數(shù)組的原型是數(shù)組,對象的原型是對象,函數(shù)的原型是函數(shù)
寬松相等 ==
- []==[]
答案是什么呢
- 答案:false
- 解析:兩個引用類型, ==比較的是引用地址
== 和 !優(yōu)先級
- []== ![]
結(jié)果是什么呢?
- (1)! 的優(yōu)先級高于== ,右邊Boolean([])是true,取返等于 false
- (2)一個引用類型和一個值去比較 把引用類型轉(zhuǎn)化成值類型,左邊0
- (3)所以 0 == false 答案是true
數(shù)字與字符串相加減
- '5' + 3
- '5' - 3
結(jié)果是多少呢?
- 答案:53 2
- 解析:加號有拼接功能,減號就是邏輯運算
- 鞏固:typeof (+"1") // "number" 對非數(shù)值+—常被用來做類型轉(zhuǎn)換相當(dāng)于Number()
一波騷操作 + - + + + - +
- 1 + - + + + - + 1
結(jié)果是多少呢
- 答案:2
- 解析:+-又是一元加和減操作符號,就是數(shù)學(xué)里的正負號。負負得正哈。
- 鞏固: 一元運算符還有一個常用的用法就是將自執(zhí)行函數(shù)的function從函數(shù)聲明變成表達式。
- 常用的有 + - ~ !void
- + function () { }
- - function () { }
- ~ function () { }
- void function () { }
又是稀疏數(shù)組?Array.prototype.map()
- var ary = Array(3);
- ary[0]=2
- ary.map(function(elem) { return '1'; });
輸出結(jié)果是多少呢?
- 稀疏數(shù)組
- 題目中的數(shù)組其實是一個長度為3, 但是沒有內(nèi)容的數(shù)組, array 上的操作會跳過這些未初始化的'坑'.
- 所以答案是 ["1", empty × 2]
這里貼上 Array.prototype.map 的 polyfill.
- Array.prototype.map = function(callback, thisArg) {
- var T, A, k;
- if (this == null) {
- throw new TypeError(' this is null or not defined');
- }
- var O = Object(this);
- var len = O.length >>> 0;
- if (typeof callback !== 'function') {
- throw new TypeError(callback + ' is not a function');
- }
- if (arguments.length > 1) {
- T = thisArg;
- }
- A = new Array(len);
- k = 0;
- while (k < len) {
- var kValue, mappedValue;
- if (k in O) {
- kValue = O[k];
- mappedValue = callback.call(T, kValue, k, O);
- A[k] = mappedValue;
- }
- k++;
- }
- return A;
- };
JS是如何存儲
- var a = 111111111111111110000,
- b = 1111;
- a + b;
這段代碼的執(zhí)行結(jié)果?
- 答案:11111111111111111000
- 解析:在JavaScript中number類型在JavaScript中以64位(8byte)來存儲。
- 這64位中有符號位1位、指數(shù)位11位、實數(shù)位52位。
- 2的53次方時,是最大值。
- 其值為:9007199254740992(0x20000000000000)。
- 超過這個值的話,運算的結(jié)果就會不對.
數(shù)組比較大小
- var a = [1, 2, 3],
- b = [1, 2, 3],
- c = [1, 2, 4]
- a == b
- a === b
- a > c
- a < c
這段代碼的執(zhí)行結(jié)果?
- 答案:false, false, false, true
- 解析:相等(==)和全等(===)還是比較引用地址
- 引用類型間比較大小是按照字典序比較,就是先比第一項誰大,相同再去比第二項。
三元運算符優(yōu)先級
- var val = 'smtg';
- console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');
這段代碼的執(zhí)行結(jié)果?
- 答案:Something
- 解析:字符串連接比三元運算有更高的優(yōu)先級
- 所以原題等價于 'Value is true' ? 'Somthing' : 'Nonthing'
- 而不是 'Value is' + (true ? 'Something' : 'Nonthing')
- 鞏固:
- 1 || fn() && fn() //1
- 1 || 1 ? 2 : 3 ; //2
原型
- var a = {}, b = Object.prototype;
- [a.prototype === b, Object.getPrototypeOf(a) === b]
執(zhí)行結(jié)果是多少呢
- 答案:false, true
- 解析:Object 的實例是 a,a上并沒有prototype屬性
- a的__poroto__ 指向的是Object.prototype,也就是Object.getPrototypeOf(a)。a的原型對象是b
原型II
- function f() {}
- var a = f.prototype, b = Object.getPrototypeOf(f);
- a === b
這段代碼的執(zhí)行結(jié)果?
- 答案:false
- 解析:a是構(gòu)造函數(shù)f的原型 : {constructor: ?}
- b是實例f的原型對象 : ? () { [native code] }
函數(shù)名稱
- function foo() { }
- var oldName = foo.name;
- foo.name = "bar";
- [oldName, foo.name]
代碼執(zhí)行結(jié)果是什么?
- 答案:["foo", "foo"]
- 解析:函數(shù)的名字不可變.
[typeof null, null instanceof Object]
- 答案:["object", false]
- 解析:null代表空對象指針,所以typeof判斷成一個對象??梢哉fJS設(shè)計上的一個BUG
- instanceof 實際上判斷的是對象上構(gòu)造函數(shù),null是空當(dāng)然不可能有構(gòu)造函數(shù)
- 鞏固:null == undefined //true null === undefined //flase
[ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]
- 答案:Error
- 解析:Math.pow (x , y) x 的 y 次冪的值
- reduce(fn,total)
- fn (total, currentValue, currentIndex, arr)
- 如果一個函數(shù)不傳初始值,數(shù)組第一個組默認為初始值.
- [3,2,1].reduce(Math.pow)
- Math.pow(3,2) //9
- Math.pow(9,1) //9
- 鞏固題,可以做一做:
- [].reduce(Math.pow) //空數(shù)組會報TypeError
- [1].reduce(Math.pow) //只有初始值就不會執(zhí)行回調(diào)函數(shù),直接返回1
- [].reduce(Math.pow,1) //只有初始值就不會執(zhí)行回調(diào)函數(shù),直接返回1
- [2].reduce(Math.pow,3) //傳入初始值,執(zhí)行回調(diào)函數(shù),返回9
replace
- "1 2 3".replace(/\d/g, parseInt)
輸出是什么呢?
- 答案:"1 NaN 3"
- 解析:replace() 回調(diào)函數(shù)的四個參數(shù):
- 1、匹配項
- 2、與模式中的子表達式匹配的字符串
- 3、出現(xiàn)的位置
- 4、stringObject 本身 。
- 如果沒有與子表達式匹配的項,第二參數(shù)為出現(xiàn)的位置.所以第一個參數(shù)是匹配項,第二個參數(shù)是位置
- parseInt('1', 0)
- parseInt('2', 2) //2進制中不可能有2
- parseInt('3', 4)
eval用法
- function f() {}
- var parent = Object.getPrototypeOf(f);
- f.name // ?
- parent.name // ?
- typeof eval(f.name) // ?
- typeof eval(parent.name) // ?
這段代碼的執(zhí)行結(jié)果?
- 答案:"f", "Empty", "function", error
- 解析:f的函數(shù)名就是f
- parent是f原型對象的名字為"" ,
- 先計算eval(f.name) 為 f,f的數(shù)據(jù)類型是function
- eval(parent.name) 為undefined, "undefined"
new Date()
- var a = new Date("2014-03-19"),
- b = new Date(2014, 03, 19);
- [a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]
這段代碼的執(zhí)行結(jié)果?
- 答案:[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); //參數(shù)要按照索引來
- Sat Apr 19 2014 00:00:00 GMT+0800 (CST)
- 月是從0索引,日期是從1
- getDay()是獲取星期幾
- getMonth()是獲取月份所以都不同
- 鞏固: [a.getDate() === b.getDate()] //true
new Date() II
- var a = Date(0);
- var b = new Date(0);
- var c = new Date();
- [a === b, b === c, a === c]
這段代碼的執(zhí)行結(jié)果?
- 答案:[false, false, false]
- 解析:當(dāng)日期被作為構(gòu)造函數(shù)調(diào)用時,它返回一個相對于劃時代的對象(JAN 01 1970)。
- 當(dāng)參數(shù)丟失時,它返回當(dāng)前日期。當(dāng)它作為函數(shù)調(diào)用時,它返回當(dāng)前時間的字符串表示形式。
- a是字符串 a === b // 數(shù)據(jù)類型都不同,肯定是false
- b是對象 b === c // 引用類型,比的是引用地址
- c也是對象 a === c // 數(shù)據(jù)類型都不同,肯定是false
new Date() III
- var a = new Date("epoch")
你認為結(jié)果是多少呢?
- 答案:Invalid Date {}
- 解析:您得到“無效日期”,這是一個實際的日期對象(一個日期的日期為true)。但無效。這是因為時間內(nèi)部保持為一個數(shù)字,在這種情況下,它是NA。
- 在chrome上是undefined
- 正確的是格式是var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);
Function.length
- var a = Function.length,
- b = new Function().length
- a === b
這段代碼的執(zhí)行結(jié)果是?
- 答案:false
- 解析:首先new在函數(shù)帶()時運算優(yōu)先級和.一樣所以從左向右執(zhí)行
- new Function() 的函數(shù)長度為0
- 鞏固:function fn () {
- var a = 1;
- }
- console.log(fn.length)
- //0 fn和new Function()一樣
- 要是看過往期的這篇文章[誠意滿滿]帶你填一些JS容易出錯的坑 就可以給我點個贊關(guān)注一下啦,下面的內(nèi)容都是這篇文章的內(nèi)容。
[1,2,5,10].sort()
不寫回調(diào)函數(shù)的話,是按照什么排序呢?
JavaScript默認使用字典序(alphanumeric)來排序。因此結(jié)果是[1,10,2,5]
正確排序的話,應(yīng)該[1,2,5,10].sort( (a,b) => a-b )
"b" + "a" + +"a" + "a"
你認為輸出是什么?
上面的表達式相當(dāng)于'b'+'a'+ (+'a')+'a',因為(+'a')是NaN,所以:
'b'+'a'+ (+'a')+'a' = 'b'+'a'+ "NaN"+'a'='baNaNa'
閉包
這是一個經(jīng)典JavaScript面試題
- let res = new Array()
- for(var i = 0; i < 10; i++){
- res.push(function(){
- return console.log(i)
- })
- }
- res[0]()
- res[1]()
- res[2]()
期望輸出的是0,1,2,實際上卻不會。原因就是涉及作用域,怎么解決呢?
- [x] 使用let代替var,形成塊級作用域
- [x] 使用bind函數(shù)。
- res.push(console.log.bind(null, i))
解法還有其他的,比如使用IIFE,形成私有作用域等等做法。
又一經(jīng)典閉包問題
- function fun(n,o) {
- console.log(o)
- return {
- fun:function(m){
- return fun(m,n);
- }
- };
- }
- var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?
- var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
- var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
留給你們思考
隱式轉(zhuǎn)換
- var a = [0];
- if (a) {
- console.log(a == true);
- } else {
- console.log("wut");
- }
你們覺得答案是多少呢?這題涉及到隱式轉(zhuǎn)換了,這個坑我自己的好好補一補
// 答案:false
再來一道?
- function fn() {
- return 20;
- }
- console.log(fn + 10); // 輸出結(jié)果是多少
- function fn() {
- return 20;
- }
- fn.toString = function() {
- return 10;
- }
- console.log(fn + 10); // 輸出結(jié)果是多少?
- function fn() {
- return 20;
- }
- fn.toString = function() {
- return 10;
- }
- fn.valueOf = function() {
- return 5;
- }
- console.log(fn + 10); // 輸出結(jié)果是多少?
說到底JS類型轉(zhuǎn)換的好好補一補了
你真的理解操作符嗎
- [1<2<3,3<2<1]
- //[false,false]
- //[true,true]
- //[false,true]
- //[true,false]
選一個吧,比較操作符,賦值運算符優(yōu)先級哪個更高呢?
0.1+0.2 !== 0.3 ?
面試的時候,問你這個問題,要是回答錯誤的話,估計面試官對基礎(chǔ)很是懷疑!!!
問你這個題目的時候,你可以牽扯出很多問題,比如JS如何存儲小數(shù)的呢?比如聊一聊二進制,比如實際開發(fā)中,遇到精度的問題,你是怎么解決的,你有什么好辦法。
聊完這個,你可以牽扯出最大安全數(shù),比如JavaScript的最大安全整數(shù)是多少,超出這個范圍的話,怎么解決精度問題呢?
ES規(guī)范中新提出的BigInt解決了什么問題呢,你又發(fā)現(xiàn)了BigInt中哪些坑呢?
如何解決精度問題呢?
這里推薦Number-Precision庫,不到1K的體積。
arguments
- function sidEffecting(ary) {
- ary[0] = ary[2];
- }
- function bar(a, b, c) {
- c = 10
- sidEffecting(arguments);
- return a + b + c;
- }
- function demo (arg) {
- arg.name = 'new Name'
- }
- console.log(bar(2, 2, 2))
涉及到ES6語法,這題答案肯定都會做是22,但是呢,稍微改變一下題目,就比較坑了….
- function sidEffecting(ary) {
- ary[0] = ary[2];
- }
- function bar(a, b, c = 4) {
- c = 10
- sidEffecting(arguments);
- return a + b + c;
- }
- function demo (arg) {
- arg.name = 'new Name'
- }
- console.log(bar(2, 2, 2))
這個答案是多少呢?根據(jù)MDN上對argument有更加準確的定義,看argument
- 當(dāng)非嚴格模式中的函數(shù)有包含剩余參數(shù)、默認參數(shù)和解構(gòu)賦值,那么arguments對象中的值不會跟蹤參數(shù)的值(反之亦然)。
找到這句話,bar函數(shù)存在默認參數(shù),并且在非嚴格模式下,所以不會跟蹤參數(shù)的值,自然結(jié)果就14
請讀者細細體會
瀏覽器
- let demo1 = {class: "Animal", name: 'sheet'};
- console.log(demo1.class)
比較流氓,這個跟瀏覽器相關(guān),class是保留字(現(xiàn)在的話,class是關(guān)鍵字),答案并不要緊,重要的是自己在取屬性名稱的時候盡量避免保留字. 如果使用的話請加引號 a['class']。
保留字vs關(guān)鍵字
個人理解的話,關(guān)鍵字就是有特殊含義的,不用用作變量名。比如
- let class = 123;
現(xiàn)在看來肯定報錯,那有什么需要我們注意的呢?
- let undefined = 123;
這樣子并不會報錯,這個跟瀏覽器有點關(guān)系,這樣子看來undefined不是關(guān)鍵字。所以為了保險起見,建議大家在判斷一個變量是不是未定義的話,盡量使用void 0 === undefined 很有可能undefined會被當(dāng)作是變量來賦值
void 0 值就是undefined
["1", "2", "3"].map(parseInt)
這個應(yīng)該是經(jīng)常遇見的題了,搞明白很簡單,map函數(shù)怎么使用,parseInt函數(shù)怎么使用
關(guān)于Array數(shù)組的話,我之前寫了一篇文章,從源碼角度解析大部分方法
點進去重溫一遍:[干貨]從詳細操作js數(shù)組到淺析v8中array.js
map接受兩個參數(shù),一個callback,一個this,即調(diào)用函數(shù)時this指向,其中callback回調(diào)函數(shù)是三個參數(shù),一個currentValue,index,array;
parseInt接受兩個參數(shù):string,radix(基數(shù))
返回NaN有兩種情況
- radix 小于 2 或大于 36 ,或
- 第一個非空格字符不能轉(zhuǎn)換為數(shù)字。
- 當(dāng)radix是0或者undefined時,又是特殊情況,具體異步MDN
- parseInt('1', 0);
- parseInt('2', 1);
- parseInt('3', 2);
兩者結(jié)合的話,結(jié)果自然很明顯,[1,NaN,NaN]
Math.min() 為什么比 Math.max() 大?
- Math.min() < Math.max() // false
按照常規(guī)思路的話,應(yīng)該是true,畢竟最小值應(yīng)該小于最大值,但是實際情況是false
原因:
- Math.min 的參數(shù)是 0 個或者多個。如果是多個參數(shù)很容易理解,返回參數(shù)中最小的。
- 如果是0個參數(shù),或者沒有參數(shù),則返回 Infinity。
- 而 Math.max() 沒有傳遞參數(shù)時返回的是 -Infinity。
要是面試官問這個問題,額。。。。
[].concat[1,2,3]
輸出是什么?注意不是[].concat([1,2,3])
- // [1,2,3]
- // Uncaught SyntaxError: ....
- // undefined
答案是undefined,原因是什么呢?
第一步計算[].concat,結(jié)果是Array.prototype.concat
第二步執(zhí)行一個逗號操作符,逗號操作符對它的每個操作對象求值(從左至右),然后返回最后一個操作對象的值。
- >1,2,3
- 返回3
第三步執(zhí)行一個數(shù)組訪問運算或?qū)傩栽L問運算
所以上面[].concat[1,2,3] 等價于Array.prototype.concat[3]
那么結(jié)果自然就是 undefined。
[1,2,NaN,3].indexOf(NaN)
//2 or -1
indexOf方法會進行嚴格相等判斷
NaN !== NaN
怎么辦呢?
- let realIsNaN = value => typeof value === 'number' && isNaN(value);
先要判斷類型,是因為字符串轉(zhuǎn)換會先轉(zhuǎn)換成數(shù)字,轉(zhuǎn)換失敗為 NaN。所以和 NaN 相等。
- isNaN('jjjj') —> true
第二種方法
- let realIsNaN = value => value !== value;
Number.isFinite & isFinite
- Number.isFinite('0') === isFinite('0')
- Number.isFinite(0) === isFinite('0')
打印結(jié)果是什么,能不能具體說一說?
Number.isFinite()檢測有窮性的值,唯一和全局isFinite()函數(shù)相比,這個方法不會強制將一個非數(shù)值的參數(shù)轉(zhuǎn)換成數(shù)值,這就意味著,只有數(shù)值類型的值,且是有窮的(finite),才返回 true。
自然答案就是 false,true
一道容易被人輕視的面試題
- function&
標題名稱:帶你填一些JS容易出錯的坑
當(dāng)前URL:http://www.fisionsoft.com.cn/article/coohcjp.html


咨詢
建站咨詢
