<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端基礎(chǔ)面試題一些你不知道的坑

          共 30298字,需瀏覽 61分鐘

           ·

          2021-04-08 10:02

          點(diǎn)擊上方“前端簡報(bào)”,選擇“設(shè)為星標(biāo)

          第一時(shí)間關(guān)注技術(shù)干貨!

          前言

          最近群里有小伙伴發(fā)了些奇奇怪怪的筆試題,還來問我,可把我難住了,當(dāng)時(shí)我內(nèi)心的表情:

          現(xiàn)在的筆試都是神仙題目,學(xué)弟可太難了,還好我靈感一現(xiàn),掏出我去年暑假刷js基礎(chǔ)時(shí),自己梳理的部分題目,分享給有需要的人。

          題目主要來自看到過的易錯(cuò)題,還有經(jīng)典的44道 JavaScript Puzzlers!,出自原文鏈接

          stackoverflow 這上面有很多Questions不錯(cuò)的,可以好好補(bǔ)一補(bǔ)基礎(chǔ)。

          GitHub倉庫點(diǎn)這里

          開始吧??

          . VS = 操作符優(yōu)先級(jí)

            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)

          留給你們思考,我可是第一遍就做錯(cuò)了(;′⌒`)

          答案 1 4

          可以好好想一想,你會(huì)茅塞頓開的。

          類數(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對(duì)象的push方法設(shè)置obj[2] = 1,obj.length++

          解釋就是第一次使用push,obj對(duì)象的push方法設(shè)置obj[3] = 2,obj.length++

          使用console.log()方法輸出的時(shí)候,因?yàn)閛bj上有l(wèi)ength屬性和splice方法,故將其作為數(shù)組輸出打印

          打印時(shí)因?yàn)閿?shù)組未設(shè)置下標(biāo)為0和1的值,故打印的結(jié)果就是empty,主動(dòng)獲取obj[0] = undefined

          非匿名自執(zhí)行函數(shù),函數(shù)名只讀

            var b = 10;
                  (function b(){
                      // 'use strict'
                      b = 20
                      console.log(b)
                  })()

          輸出的結(jié)果是什么?

          Function b
          - 如標(biāo)題一樣,非匿名自執(zhí)行函數(shù),函數(shù)名不可以修改,嚴(yán)格模式下會(huì)TypeError,
          - 非嚴(yán)格模式下,不報(bào)錯(cuò),修改也沒有用。
          - 查找變量b時(shí),立即執(zhí)行函數(shù)會(huì)有內(nèi)部作用域,會(huì)先去查找是否有b變量的聲明,有的話,直接復(fù)制
          - 確實(shí)發(fā)現(xiàn)具名函數(shù)Function b(){} 所以就拿來做b的值
          - IIFE的函數(shù)內(nèi)部無法進(jìn)行復(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變量的時(shí)候,發(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é)果是多少呢?

          這個(gè)問題應(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 會(huì)被提升

          相當(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 因?yàn)閚ame已經(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);

          一個(gè)知識(shí)點(diǎn):Infinity

          在 JS 里, Math.pow(2, 53) == 9007199254740992 是可以表示的最大值. 最大值加一還是最大值. 所以循環(huán)不會(huì)停.

          稀疏數(shù)組與密數(shù)組

          var ary = [0,1,2];
          ary[10] = 10;
          ary.filter(function(x) { return x === undefined;});

          執(zhí)行結(jié)果如何呢?

          做這個(gè)題目,你需要了解稀疏數(shù)組和密集數(shù)組

          • 譯 JavaScript中的稀疏數(shù)組與密集數(shù)組
          • Array/filter

          看過源碼的同學(xué)應(yīng)該知道,filter源碼中,會(huì)去判斷數(shù)組的這個(gè)索引值是不是數(shù)組的一個(gè)屬性,有興趣的同學(xué)可以看看我寫的這篇關(guān)于數(shù)組的:[干貨??]從詳細(xì)操作js數(shù)組到淺析v8中array.js

          in ary; => true
          in ary; => false
          10 in ary; => true
          也就是說 從 3 - 9 都是沒有初始化的'坑'!, 這些索引并不存在與數(shù)組中. 在 array 的函數(shù)調(diào)用的時(shí)候是會(huì)跳過這些'坑'的.

          所以答案就是[]

          浮點(diǎn)運(yùn)算

          var two   = 0.2
          var one   = 0.1
          var eight = 0.8
          var six   = 0.6
          [two - one == one, eight - six == two]

          你認(rèn)為結(jié)果是多少呢?面試遇到這個(gè)問題,應(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'));

          運(yùn)行結(jié)果如何呢?

          switch 是嚴(yán)格比較, String 實(shí)例和 字符串不一樣.
          答案自然是'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'));

          運(yùn)行結(jié)果呢?

          答案:Case A
          解析:String('A')就是返回一個(gè)字符串

          %運(yùn)算符

          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);

          運(yùn)行的結(jié)果如何呢?

          答案:[truetruetruefalsefalse]
          解析:%如果不是數(shù)值會(huì)調(diào)用Number()去轉(zhuǎn)化
               '13' % 2       // 1
                Infinity % 2  //NaN  Infinity 是無窮大
                -9 % 2        // -1
          鞏固:9 % -2        // 1   余數(shù)的正負(fù)號(hào)隨第一個(gè)操作數(shù)

          數(shù)組的原型是什么

          Array.isArray( Array.prototype )

          這段代碼的執(zhí)行結(jié)果?

          答案:true
          解析:Array.prototype是一個(gè)數(shù)組
          數(shù)組的原型是數(shù)組,對(duì)象的原型是對(duì)象,函數(shù)的原型是函數(shù)

          寬松相等 ==

          []==[]

          答案是什么呢

          答案:false
          解析:兩個(gè)引用類型, ==比較的是引用地址

          == 和 !優(yōu)先級(jí)

          []== ![] 

          結(jié)果是什么呢?

          (1)! 的優(yōu)先級(jí)高于== ,右邊Boolean([])是true,取返等于 false
          (2)一個(gè)引用類型和一個(gè)值去比較 把引用類型轉(zhuǎn)化成值類型,左邊0
          (3)所以 0 == false  答案是true

          數(shù)字與字符串相加減

          '5' + 3
          '5' - 3

          結(jié)果是多少呢?

          答案:53  2
          解析:加號(hào)有拼接功能,減號(hào)就是邏輯運(yùn)算
          鞏固:typeof (+"1")   // "number" 對(duì)非數(shù)值+—常被用來做類型轉(zhuǎn)換相當(dāng)于Number()

          一波騷操作  + - + + + - +

          1 + - + + + - + 1

          結(jié)果是多少呢

          答案:2
          解析:+-又是一元加和減操作符號(hào),就是數(shù)學(xué)里的正負(fù)號(hào)。負(fù)負(fù)得正哈。 
          鞏固: 一元運(yùn)算符還有一個(gè)常用的用法就是將自執(zhí)行函數(shù)的function從函數(shù)聲明變成表達(dá)式。
                常用的有 + - ~ !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ù)組其實(shí)是一個(gè)長度為3, 但是沒有內(nèi)容的數(shù)組, array 上的操作會(huì)跳過這些未初始化的'坑'.

          所以答案是 ["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是如何存儲(chǔ)

          var a = 111111111111111110000,
          b = 1111;
          a + b;

          這段代碼的執(zhí)行結(jié)果?

          答案:11111111111111111000
          解析:在JavaScript中number類型在JavaScript中以64位(8byte)來存儲(chǔ)。
          這64位中有符號(hào)位1位、指數(shù)位11位、實(shí)數(shù)位52位。
          2的53次方時(shí),是最大值。
          其值為:9007199254740992(0x20000000000000)。
          超過這個(gè)值的話,運(yùn)算的結(jié)果就會(huì)不對(duì).

          數(shù)組比較大小

          var a = [1, 2, 3],
              b = [1, 2, 3],
              c = [1, 2, 4]
          a ==  b
          a === b
          a >   c
          a <   c

          這段代碼的執(zhí)行結(jié)果?

          答案:falsefalsefalsetrue
          解析:相等(==)和全等(===)還是比較引用地址
               引用類型間比較大小是按照字典序比較,就是先比第一項(xiàng)誰大,相同再去比第二項(xiàng)。

          三元運(yùn)算符優(yōu)先級(jí)

          var val = 'smtg';
          console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');

          這段代碼的執(zhí)行結(jié)果?

          答案:Something
          解析:字符串連接比三元運(yùn)算有更高的優(yōu)先級(jí) 
               所以原題等價(jià)于 '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é)果是多少呢

          答案:falsetrue
          解析:Object 的實(shí)例是 a,a上并沒有prototype屬性
               a的__poroto__ 指向的是Object.prototype,也就是Object.getPrototypeOf(a)。a的原型對(duì)象是b

          原型II

          function f() {}
          var a = f.prototype, b = Object.getPrototypeOf(f);
          a === b         

          這段代碼的執(zhí)行結(jié)果?

          答案:false
          解析:a是構(gòu)造函數(shù)f的原型 : {constructor: ?}
          b是實(shí)例f的原型對(duì)象 : ? () { [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代表空對(duì)象指針,所以typeof判斷成一個(gè)對(duì)象。可以說JS設(shè)計(jì)上的一個(gè)BUG
               instanceof 實(shí)際上判斷的是對(duì)象上構(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) 
                   如果一個(gè)函數(shù)不傳初始值,數(shù)組第一個(gè)組默認(rèn)為初始值.
                   [3,2,1].reduce(Math.pow)
                   Math.pow(3,2) //9
                   Math.pow(9,1) //9

          鞏固題,可以做一做:
            [].reduce(Math.pow)       //空數(shù)組會(huì)報(bào)TypeError
               [1].reduce(Math.pow)      //只有初始值就不會(huì)執(zhí)行回調(diào)函數(shù),直接返回1
               [].reduce(Math.pow,1)     //只有初始值就不會(huì)執(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ù)的四個(gè)參數(shù):
                1、匹配項(xiàng)  
                2、與模式中的子表達(dá)式匹配的字符串  
                3、出現(xiàn)的位置  
                4、stringObject 本身 。
          如果沒有與子表達(dá)式匹配的項(xiàng),第二參數(shù)為出現(xiàn)的位置.所以第一個(gè)參數(shù)是匹配項(xiàng),第二個(gè)參數(shù)是位置
           parseInt('1', 0)
           parseInt('2', 2)  //2進(jìn)制中不可能有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原型對(duì)象的名字為"" ,
               先計(jì)算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é)果?

          答案:[falsefalse]
          解析:var a = new Date("2014-03-19")    //能夠識(shí)別這樣的字符串,返回想要的日期
                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é)果?

          答案:[falsefalsefalse]
          解析:當(dāng)日期被作為構(gòu)造函數(shù)調(diào)用時(shí),它返回一個(gè)相對(duì)于劃時(shí)代的對(duì)象(JAN 01 1970)。
          當(dāng)參數(shù)丟失時(shí),它返回當(dāng)前日期。當(dāng)它作為函數(shù)調(diào)用時(shí),它返回當(dāng)前時(shí)間的字符串表示形式。
          a是字符串   a === b // 數(shù)據(jù)類型都不同,肯定是false
          b是對(duì)象     b === c // 引用類型,比的是引用地址
          c也是對(duì)象   a === c // 數(shù)據(jù)類型都不同,肯定是false

          new  Date() III

          var a = new Date("epoch")

          你認(rèn)為結(jié)果是多少呢?

          答案:Invalid Date {}
          解析:您得到“無效日期”,這是一個(gè)實(shí)際的日期對(duì)象(一個(gè)日期的日期為true)。但無效。這是因?yàn)闀r(shí)間內(nèi)部保持為一個(gè)數(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ù)帶()時(shí)運(yùn)算優(yōu)先級(jí)和.一樣所以從左向右執(zhí)行
               new Function() 的函數(shù)長度為0
          鞏固:function fn () {
                   var a = 1;
                }
                console.log(fn.length) 
                //0 fn和new Function()一樣

          要是看過往期的這篇文章[誠意滿滿?]帶你填一些JS容易出錯(cuò)的坑 就可以給我點(diǎn)個(gè)贊??關(guān)注一下啦,下面的內(nèi)容都是這篇文章的內(nèi)容。

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

          不寫回調(diào)函數(shù)的話,是按照什么排序呢?

          JavaScript默認(rèn)使用字典序(alphanumeric)來排序。因此結(jié)果是[1,10,2,5]

          正確排序的話,應(yīng)該[1,2,5,10].sort( (a,b) => a-b )

          "b" + "a" + +"a" + "a"

          你認(rèn)為輸出是什么?

          上面的表達(dá)式相當(dāng)于'b'+'a'+ (+'a')+'a',因?yàn)椋?'a')是NaN,所以:

          'b'+'a'+ (+'a')+'a' = 'b'+'a'+ "NaN"+'a'='baNaNa'

          閉包

          這是一個(gè)經(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,實(shí)際上卻不會(huì)。原因就是涉及作用域,怎么解決呢?

          • [x] 使用let代替var,形成塊級(jí)作用域
          • [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)換了,這個(gè)坑我自己的好好補(bǔ)一補(bǔ)

          // 答案: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)換的好好補(bǔ)一補(bǔ)了

          你真的理解操作符嗎

          [1<2<3,3<2<1]
          //[false,false]
          //[true,true]
          //[false,true]
          //[true,false]

          選一個(gè)吧,比較操作符,賦值運(yùn)算符優(yōu)先級(jí)哪個(gè)更高呢?

          0.1+0.2  !== 0.3  ?

          面試的時(shí)候,問你這個(gè)問題,要是回答錯(cuò)誤的話,估計(jì)面試官對(duì)基礎(chǔ)很是懷疑!!!

          問你這個(gè)題目的時(shí)候,你可以牽扯出很多問題,比如JS如何存儲(chǔ)小數(shù)的呢?比如聊一聊二進(jìn)制,比如實(shí)際開發(fā)中,遇到精度的問題,你是怎么解決的,你有什么好辦法。

          聊完這個(gè),你可以牽扯出最大安全數(shù),比如JavaScript的最大安全整數(shù)是多少,超出這個(gè)范圍的話,怎么解決精度問題呢?

          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(222))

          涉及到ES6語法,這題答案肯定都會(huì)做是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))

          這個(gè)答案是多少呢?根據(jù)MDN上對(duì)argument有更加準(zhǔn)確的定義,看argument

          當(dāng)非嚴(yán)格模式中的函數(shù)包含剩余參數(shù)、默認(rèn)參數(shù)和解構(gòu)賦值,那么arguments對(duì)象中的值不會(huì)跟蹤參數(shù)的值(反之亦然)。

          找到這句話,bar函數(shù)存在默認(rèn)參數(shù),并且在非嚴(yán)格模式下,所以不會(huì)跟蹤參數(shù)的值,自然結(jié)果就14

          請讀者細(xì)細(xì)體會(huì)

          瀏覽器懵逼史

            let demo1 = {class"Animal"name'sheet'};
                  console.log(demo1.class)

          比較流氓,這個(gè)跟瀏覽器相關(guān),class是保留字(現(xiàn)在的話,class是關(guān)鍵字),答案并不要緊,重要的是自己在取屬性名稱的時(shí)候盡量避免保留字. 如果使用的話請加引號(hào) a['class']。

          保留字vs關(guān)鍵字

          個(gè)人理解的話,關(guān)鍵字就是有特殊含義的,不用用作變量名。比如

          let class = 123;

          現(xiàn)在看來肯定報(bào)錯(cuò),那有什么需要我們注意的呢?

          let undefined = 123;

          這樣子并不會(huì)報(bào)錯(cuò),這個(gè)跟瀏覽器有點(diǎn)關(guān)系,這樣子看來undefined不是關(guān)鍵字。所以為了保險(xiǎn)起見,建議大家在判斷一個(gè)變量是不是未定義的話,盡量使用void 0 === undefined 很有可能undefined會(huì)被當(dāng)作是變量來賦值

          void 0 值就是undefined

          ["1", "2", "3"].map(parseInt)

          這個(gè)應(yīng)該是經(jīng)常遇見的題了,搞明白很簡單,map函數(shù)怎么使用,parseInt函數(shù)怎么使用

          關(guān)于Array數(shù)組的話,我之前寫了一篇文章,從源碼角度解析大部分方法

          點(diǎn)進(jìn)去重溫一遍:[干貨??]從詳細(xì)操作js數(shù)組到淺析v8中array.js

          map接受兩個(gè)參數(shù),一個(gè)callback,一個(gè)this,即調(diào)用函數(shù)時(shí)this指向,其中callback回調(diào)函數(shù)是三個(gè)參數(shù),一個(gè)currentValue,index,array;

          parseInt接受兩個(gè)參數(shù):string,radix(基數(shù))

          返回NaN有兩種情況

          • radix 小于 2 或大于 36 ,或
          • 第一個(gè)非空格字符不能轉(zhuǎn)換為數(shù)字。
          • 當(dāng)radix是0或者undefined時(shí),又是特殊情況,具體異步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)該小于最大值,但是實(shí)際情況是false

          原因:

          • Math.min 的參數(shù)是 0 個(gè)或者多個(gè)。如果是多個(gè)參數(shù)很容易理解,返回參數(shù)中最小的。
          • 如果是0個(gè)參數(shù),或者沒有參數(shù),則返回 Infinity
          • 而 Math.max() 沒有傳遞參數(shù)時(shí)返回的是 -Infinity。

          要是面試官問這個(gè)問題,額。。。。

          [].concat[1,2,3]

          輸出是什么?注意不是[].concat([1,2,3])

          // [1,2,3]

          // Uncaught SyntaxError: ....

          // undefined

          答案是undefined,原因是什么呢?

          1. 第一步計(jì)算[].concat,結(jié)果是Array.prototype.concat

          2. 第二步執(zhí)行一個(gè)逗號(hào)操作符,逗號(hào)操作符對(duì)它的每個(gè)操作對(duì)象求值(從左至右),然后返回最后一個(gè)操作對(duì)象的值。

            >1,2,3
            返回3
          3. 第三步執(zhí)行一個(gè)數(shù)組訪問運(yùn)算或?qū)傩栽L問運(yùn)算

          所以上面[].concat[1,2,3] 等價(jià)于Array.prototype.concat[3]

          那么結(jié)果自然就是 undefined

          [1,2,NaN,3].indexOf(NaN)

          //2 or -1

          • indexOf方法會(huì)進(jìn)行嚴(yán)格相等判斷
          • NaN !== NaN

          怎么辦呢?

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

          先要判斷類型,是因?yàn)樽址D(zhuǎn)換會(huì)先轉(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ù)相比,這個(gè)方法不會(huì)強(qiáng)制將一個(gè)非數(shù)值的參數(shù)轉(zhuǎn)換成數(shù)值,這就意味著,只有數(shù)值類型的值,且是有窮的(finite),才返回 true

          自然答案就是 false,true

          一道容易被人輕視的面試題

          function Foo() {
              getName = function () { alert (1); };
              return this;
          }
          Foo.getName = function () { alert (2);};
          Foo.prototype.getName = function () { alert (3);};
          var getName = function () { alert (4);};
          function getName() { alert (5);}

          //請寫出以下輸出結(jié)果:
          Foo.getName();
          getName();
          Foo().getName();
          getName();
          new Foo.getName();
          new Foo().getName();
          new new Foo().getName();

          push方法

          let newList = [1,2,3].push(4)
          console.log(newList.push(4))

          認(rèn)為輸出什么?

          // Error

          原因在于Array.prototype.push()返回的是新數(shù)組的長度,所以呢4.push(5)自然Error


          自動(dòng)分號(hào)插入

          function foo1()
          {
           return {
               bar"hello"
           };
          }

          function foo2()
          {
           return
           {
               bar"hello"
           };
          }
          var a=foo1();
          var b=foo2();
          console.log(a) //Object {bar: "hello"}
          console.log(b) //underfind
          //仔細(xì)看就知道了
          // 會(huì)在第10行加入一個(gè)`;`

          會(huì)在第10行自動(dòng)加一個(gè)分號(hào); 所以返回的就是undefined


          let var

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

          上面的let a = b = 0; 等價(jià)于 window.b  = 0, let a = b;


          眼力題

          const length = 4;
          const numbers = [];
          for (var i = 0; i < length; i++);{
            numbers.push(i + 1);
          }

          numbers; // => ???

          唯一需要注意的就是for語句后面帶了;沙雕題

          加了;,會(huì)認(rèn)為for執(zhí)行完,所以指定的都是空語句,最后numbers為[5]


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

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

          使用的就是方括號(hào)表示法獲取字符串特定索引的字符,值得注意的是,IE7低版本使用的是charAt()

          所以這題輸出o


          !==

          const name = 'TianTianUp'
          console.log(!typeof name === 'string')
          console.log(!typeof name === 'object')

          typeof name 返回的是 ’string‘, 字符串’string‘是一個(gè)truthy值。因此!typeof name 返回一個(gè)布爾值false。所以

          false === ’string'

          和 false === ’object‘返回false

          (檢測一個(gè)類型的值話,我們應(yīng)該使用 !==而不是!typeof)


          forEach

          const nums = [1, 2, 3, 4, 5, 6];
          let firstEven;
          nums.forEach(n => {
            if (n % 2 ===0 ) {
              firstEven = n;
              return n;
            }
          });
          console.log(firstEven);

          唯一需要注意的就是forEach源碼是怎么寫的,看過源碼的都知道,forEach使用return是不能中止循環(huán)的,或者說每一次調(diào)用callback函數(shù),終止的是當(dāng)前的一次,而不是整個(gè)循環(huán)。

          結(jié)果自然就是6

          END



          如果覺得這篇文章還不錯(cuò)
          點(diǎn)擊下面卡片關(guān)注我
          來個(gè)【分享、點(diǎn)贊、在看】三連支持一下吧

             “分享、點(diǎn)贊在看” 支持一波  

          瀏覽 112
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  www.污污污在线观看 | 大香蕉天天 | 亚洲乱仑小说图片 | 久久免费成人视频 | 日日干视频 |