前言

漫漫编程路,总有一些坑让你泪如泉涌。

[1,2,5,10].sort()

不写回调函数的话,是按照什么排序呢?

JavaScript默许运用字典序(alphanumeric)来排序。因此效果是[1,10,I G J 9 p m 9 x ]2,5]

正确排序的话,应该[1,2,5,10].sort( (a,b) => a-b )

“b” + “a” + +”^ O c q r ^ J Z 8a” + “a”

你以为输出是什么s y c n R E

上面的表达式相当于’bv o 9 +‘+’a’+ (+’a’)+’a’,由于(+’a’)m b 8 G _ f = m *是NaN,所以:

‘b’+’a’+ (+’a’)+’a’ = ‘b’+’a’+ “NaN”+’a’=’baNaNa’

闭包

这是一个经典JavaScript面试题

  let res = n9 6 - = 1 G ` A Oew Array()
        for(var i = 0; i < 10; i++){
            res.push(function(){
                return console.log(i)
            })
        }
        res[0]()
        res[1]()
        res[2]()

希望输出的是0,1,2,实践上却不会。原因就是涉及作用域,怎样处理A ` n U / / I #呢?

  • [x] 运用let替代var,构成块级作用域
  • [x] 运用bind函数。
res.push(console.log.bind(null, i))

解法还有其他q k M G A + –的,比如运% n E Y 6 f [用IIFE,构成私有作用域等等做法。

又一经典闭包问题

function fun(n,_ m x 9 P p [o) {
  console.log(o)
  req $ c q = _ hturn {
    fun:function(m){
      return fun(m,n);C f & ( Y c
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,?
var b = fun(0).fu* O c Mn(1b ` h D W G u G A).funA h n $(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//unW ` _defined,?,?,?

留给你们考虑

隐式转N 0 C e

var a = [0]? & t t + ?;
if (a) {
  console.log(a == true);
} else {
  console.log("wut");
}

你们觉得答案是多少呢?这题涉及到隐式M / P转化了,这个坑我自己的好好补一补

// 答案:false

再来一道?

function fn() {
    return 20;
}
console.log(fn +& s 2 10); //p u M D 输出成; t Y K } b果是多少
function fn() {
    return 20;
}
fn.toString = function() {
    return 10;
}
console.log(fn + 10);  // 输出效果是多少?
function fn() {
    return 20;
}

fn.toString = function() {
    return 10;
}

fn.valueOf = f; m s } 0 s b ;unction() {
    return 5;
}

console.log(fn + 10); //Q 0 d z O ^ : 输出效果是多少?

说到底JS类型转化的好好补一补了

你真的了解a m $ k O k 2 8 ^操作符吗

[1<2&ltg P t 7 Y } : k;3,3<2<1]
//[false,false]
//[true,true]
//[false,true]
//[true,false]

选一个吧,比较操作符,赋值运算符优先级哪个更高呢?

0.1+0.2 !== 0.3 ?

面试的时分,问你这个问题,要是答复错误的话,估量面试官对根底很是怀疑!!!? : ^ [ C 1

问你这个标题的时分,你可以牵扯出许多问题,比如JS怎样存储小数的呢?比如聊一聊二进制,比如实践开V + h B l v l `发中,遇到精度的问题,你是怎样处理的,你有什么好方法。

聊完这个Y R ] $ B,你可以牵扯出最大安全数,比如JavaScript的最大安全整a * P @数是多少,超出~ P @ u 这个规模V E _ m V x m的话,怎样处理精度问题呢?

ES规范中新提出的BigInt处理了什么问题呢,你又发现了BigInt中哪些坑呢?

怎样处理精度问题呢?

这儿举荐Number-Precision库,~ G o = j K w不到1K的体积。

arguments

  function sidEffecting(ary) {
            ary[0] = ary[2]T L [ x f V 7 W 0;
        }
        function bar(a,A ^ g v b, c) {
            c = 10
            sidEffecting(arguments);
            return a + b + c;
        }
        function demo (arg) {
            arg.name = '# E c ] J k $ 9new Name'
        }
        console.& E O M O K a 9 olog(bar(2, 2, 2))

涉及到ES6语法,这题答案必定都会做是22,但是呢,稍微U 0 9 u改动一下标题,就比较坑了….

  function sidEffecM ) 8ting(ary) {
            ary[0] = ary[2];
        }
        function bar(a, b, c = 4) {K u S
            c = 10
            sidEffectingd y n L(arguments);
            return a + b + c;
        }
        function demo (arg) {
            arg.name = 'new Name'
        }
        console.log(bar(2, 2, 2))

这个答案是多少呢?根据MDw p V } |N上对argument有愈加准确的定义,看argument

当非严峻形式中的函数= } X X U / !包括剩余参数、默许参数和解构赋值,那么arguments方针中的值不会– ^ _ T S跟踪参数的值(反之亦然)。

找到这句话,bar函数存在默许参数,并且在非严峻形式下,所以不会跟踪参数的值,天然效果就14

请读者细细领会

浏览器懵逼史

  let demo1 = {c0 Y & alass: "Animal", name: 'sheet'};
        console.log(demo1.class)

比较流氓,这个跟浏览器相关,class是保存字? 0 ^ 3 f(现在的话,class是关键字),答案并不要紧,重要的是自己在取特点称号的时分尽量避免保存B } [ ? X g 6 =字. 假如运用的话请加引号 a[‘class’]。

保存字vs关键字

个人了解的话,关键字就是有特别含义的e j ] 5 @ ? R,不用用作变量名。比如

let class = 123;

现在看来必定报错,那有什么需求我们留心的呢?

let undefined = 123;

这姿势并不1 n 4会报错,这个跟浏览器有点联系,这姿势看来undefined不是关键字。所以为了保险起见,主张我们在判别一个变量是不是未定义的话,尽量E s : G 5 –运用void 0 === undef, f & n T K Lined 很有或许undefined会被当作是变量来赋值

v? ? koid 0 值就是undefined

[“1”, “2”, “3”].map(parseInt)

这个应该是常常遇见的题了,搞明白很简略,map函数怎样运用,parseInt函数怎样运用

关于Array数组的话,我之前写了一篇文g s f Z : , w f章,从源码视点解析大部分方法

点进去重温一遍u o b:[干货]从具体Z z o操作js数组到浅析v8中array.js

map接( E 4 D g W : =受两个参数,一个callba{ O S + 3 ^ @ 8 %ck,一个this,N # W ~ x b ( v即调用函数时this指向,其间callback回调函数是三个参数,一个cu? x 3 N i v 7rrent? I { s 6 ,Value,index,array;

parseInt接受两个参数:string,radix(基数)

回来NaN有两种情L A ,

  • radix 小于 2 或大于 36 ,或
  • 第一个非{ L *空格_ b L 7 u B y B字符不能转化为数字。
  • 当ray L 5 Tdix是0或g N h 7 M ( j h许undeft c q Gined时,又是特别情况,具体异步MDN
pars. a t K / EeInt('1', 0);
pL ` z &arseInt('2', 1);
parseInt('3', 2);

两者结合的话,效果天然很明显,[1,NaN,NaN]

Math.min() 为什么比 Math.max() 大?

  Math.min() < Math.max() // false

按照惯例思路的话,应该是true,终究最小值应该小于最大值,但是实践情况是fao 7 )lse

原因:

  • Math.min 的参数是 0 个或许多个。假如是$ F 1 & T 0 e S多个参数很简略了解,回来参数中最小的。
  • 假如是0个参数,或许没有参数,则回来 Infinity
  • 而 Math.max() 没有传递参数时回来的是 -Infinity。

要是面试官问这个问题,额。。。。

[].concat[1,2,3]

输出是什么?留心不是[].concat([1,2S Z f L # ; *,3])

// [1,2,3]

// Uncaught SyntaxError: ....

// undefined

答案是undefined,原因是什么4 f m 2 G } !呢?

  1. 第一步核算[].concat,效果是Array.prototype.concat

  2. 第二步实行一个逗号操作符,逗号操作符对它的每个操作方针求值(从左至右),然后回来最终一个操作目 g n o标的值。

    >1,2,3
    回来3
    
  3. 第三步实行一个数组访问运算或特点访问运算

所以上面[].concat[1,2,3r % Q b S] 等价于Array.prototype.concat[3]

那么效果天然就是 undefined

[1,2,NaN,3].ind1 y b n q 2 Xeo } ` 8 ) . ,xOf(NaN)

//2 or -1

  • indexOf方法会进行严峻相等判别
  • NaN !== NaN

怎样办呢?

let realIsNaN = value => typeof value === 'number' && isNaN(value);

先要判别类型,是由于f N e ! ] 1 K a字符串转化会先转化成数字,转化失利为e k NaN。所以和 NaN 相等。

isNaN('jjjj') —> true

第二种方法

let realIsNaN = value => value !== value;

Number.isFinite & isFinite

Number.isFinite('0') === isFinite('0')

Number.if K | H 0 osFinite(0) ===) 9 i  N d L isFf 0 n ! ] Cinite('0'w l T o # 4 z h)

打印效果是什么,能不能具体说一说?

Num% [ j j l Z ber.isFinite()检测有穷性的值,仅有和大局isFinite()函数相比x 7 . – , ZE g r a o Y z I这个方法不会强制将一个非数值5 j : T +的参数转化成数值,这就意味着,只需数值类型的值,且是有穷的(finite),才回来 true

天然答案就是 false,true

一道简略被人小看的面6 i `试题

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = func9 T j z ]tion () { alert (3);};
var getName = function () { alert (4);};
function gel ! tName() { alert (5);}

//请写出以下输出效果:
Foo.getName();
getName();
Foo()( e N  = 1 b.getName();
getName();
new Foo.getN6 _ m 0 H 2ame();
new Foo().getName();
new new Foo().getName();

push方法

let newList = [1,2,3].push(4)
console.l1 Y  ; 8 tog(newList.push(4))

以为输出什R j u f ( Y } 么?

// Error

原因在于Array.prototype.pu
shW 2 : F X()回来的是新数组的长度,所以呢4.push(5)天然Error

7.1$ 8 o T ! ;3更新一波

| 3 ` h X u Y动分号插入

function fp C 0 z r $ ? *oo1()
{
 return {
     bar: "hell 5 I ] q M ] Ho"
 };
}

function foo2()
{
 return
 {
     bar: "hello"
 };
}
var a=foo1();
var b Y _ j s=foo2(s & X v ? ^  ])c + P [ a;
console.log(a) //Object {bar: "hello"}
ch W f ~ Yonsole.log(b) //underfind
//仔细看就知道了
// 会在第10行参与一个`;`

会在第10行自动加一个分号; 所以回来的便b G y A t % M是undefined


let var

function foo() {
let a = b = 0;
a++;
return2 f , a;
}
foo();
typeof a; // => ???
typeof b; // => ???

上面的let a = b = 0; 等价于 window.b = 0, let a = b;


眼力题

const length = 4;
const numbers = [];
for (var i = 0; i < lengt2 q ?  . Y | /h; i++);{
  numbers.push(i + 1);
}

numbers; // => ???

仅有需求留心的就是fo. & K x & J | : Yr语句后面带了;沙雕题

加了;,会以为for实行完,所以指定$ A V 1的都是空语句,最终numbers为[5]


获取字符串中特定索引字符

console.log('Hello World'[4])

运用的就是方括号表示法获取字– p c c # 3 g符串特定索引的字符,值得留心的是,IE7低版本运用的是charAj v + Gt()

所以这题输出o


!==

const name = 'TianTianUpI D r ='
console.log(!typeof name === 'string')
console.n i - ) Dlog(!typeof name === 'object')

typeof name 回来的是 ’strin{ _ ?g‘, 字符串’] t g $ K gstring‘是~ f @ – S一个truthy值。因此!typeof name 回来一个布尔值C B 8 8 l |false。所以

false === ’string’

和 false === ’object‘回来false

(检N D v 9 k ( (测一个类型的值话,我们应该运用 !==而不是!typeof)


forEach

const nums = [1, 2, 3,| ,  [ D 4, 5, 6];
le1 v K $ H W 3 Mt firstEven;
nums.forEach(n =>E s H K n {
  if (n % 2 ===- E S - 6 ( }0 ) {
    firstEven = n;
    ret4 A N t N r V / curn n;
  }
})z 7 r / $;
console.loN G g(firstEven);

仅有需求留心的就是forEach源码是怎样写的,看过源码的都知道,forEach运用return是不能连续循环的,或许说每一次调用callback函数,中止的是其时的一次,而b ^ 1 i s L不是整个循环。

A n /果天然就是6


持续更新中

有不错的标题,或许是JS中简略犯错的坑,掘金网友可以提出来❤r j E + , C️,我会更新的啦

❤️ 感谢我们

假如你觉得这篇内容对你挺有有R 0 ^ U L p K N协助的话:

  1. 点赞支持下吧,让更多的人也能看到这篇内容(保藏不点赞,都是耍流氓 -_-)

  2. 欢迎在留言区与我共享( x x y你的主见,也欢迎你h W 2 O | , ^在留言区记载你的考虑进程。

  3. 觉得不错的话,也可以看看往期文章:

    [z C ( O % R诚意满满]Chrome DevTools调试小技巧,效率➡️

    [实5 r _ Z 8用]举荐一些十分棒的前端网站

    [干货]从具体操作js数组到浅析v8中array.js

    [1.2W字]写给女友的秘籍-浏览器作业原理(上)篇

    [1.1W字]写给女友的秘籍-浏览器作业原理(烘托流程)篇

    [主张]再来100道JS输命题酸爽持续(共1.8W字+巩固JS根底)

    [诚意满满✍]带你填一些JS简略犯错的坑