JS面試題

1. 數據類型

  • number
  • string
  • boolean
  • symbol
  • null
  • undefined
  • object

2. string方法

  • string.substr
string.substr(start,length) // 若length不寫則延續到最后
  • string.substring
string.substring(start,end) // 哪個小就把哪個看作start

2. promise怎么用

  • 生成promise
function(){
  return new Promise(function(resolve,reject){
    if(成功){
      resolve()
    }else{
      reject()
    }
  })
}
  • then
$.ajax(...).then(成功函數,失敗函數)
  • then是鏈式的
$.ajax(...).then(成功函數1,失敗函數1).then(成功函數2,失敗函數2)
//ajax返回404,失敗函數1執行,成功函數2執行

3. 手寫ajax

let request = new XMLHttpRequest();
request.open('POST','/xxx');
request.onreadystatechange = ()=>{
  if(request.readyState === 4 && request.status === 200){
    var value = JSON.parse(request.responseText);
  }
}
// 是post才用在send里寫東西,不然可以直接send()
request.send('a=1&b=2');

4. 手寫閉包

function createAdder(){
  let n=1;
  return function(){
    n+=1;
    console.log('n', n)
  }
}

let adder = createAdder();
adder()  //n===2
adder()  //n===3
console.log(n)  //n is not defined

5. this是什么

  1. fn()里面的this正常模式下是Window
  2. a.b.c.fn()里面的this就是a.b.c
  3. new F()里面的this就是F()對象
  4. () => {console.log(this)}里面的this就是外面的this

6. 立即執行函數

!function(){}()
作用是創造一個函數作用域,防止污染全局變量
es6新語法可以代替立即執行函數

{
  let name = 'p'  //用let聲明變量即可
}

7. async/await語法

async init() {
  this.loading = true
  const { getImgTaskNumber, getCountByStatus } = this.$api.task
  const promises = []
  for (const index in this.imageData) {
    const promise = getImgTaskNumber(this.imageData[index].name)
    promises.push(promise)
    const info = await promise
    this.imageData[index]['taskCounts'] = info.count
    this.imageData[index]['time'] = info.overdue
  }
  let promise = getCountByStatus('unallocated')
  promises.push(promise)
  this.imgDetected = await promise
  promise = getCountByStatus('labeling')
  this.labeling = await promise
  promises.push(promise)
  await Promise.all(promises)
  this.loading = false
}

8. 深拷貝

  1. 用JSON深拷貝
let a = {...}
let b = JSON.parse(JSON.stringify(a))

但這個方法不支持函數、引用、undefined、正則...

  1. 遞歸拷貝
let china = {
  nation : '中國',
  birthplaces:['北京','上海','廣州'],
  skincolor :'yellow',
  friends:['sk','ls']
}
//深復制,要想達到深復制就需要用遞歸
function deepCopy(o, c){
  let copy = c || {}
  for(let i in o){
    if(typeof o[i] === 'object'){  //要考慮深復制問題了
      if(o[i].constructor === Array){
      //這是數組
        copy[i] =[]
      }else{
      //這是對象
        copy[i] = {}
      }
      deepCopy(o[i],copy[i])
    }else{
      copy[i] = o[i]
    }
  }
  return copy
}
let result = {name:'result'}
result = deepCopy(china,result)
console.dir(result)

9. 數組去重

  1. ES5(計數排序的邏輯)

    function distinct(a) {
      let obj = {}
      let result = []
      a.forEach(value => {
        if (!obj[value]) {
          obj[value] = 1
          result.push(value)
          }
        })
      return result
    }
    let a = [1,1,1,1,2,3,4,5,6,5,3,2,4,56,56,4,1,2,7]
    let b = distinct(a)
    console.log(b)
    
  2. ES6

    function distinct2(array){
     return Array.from(new Set(array));
    }
    distinct2([1,1,2,3]) //[1,2,3]
    

10. 用正則實現string.trim()

function trim(string){
  return string.replace(/^\s+|\s+$/g,'') 
  //^\s+表示開頭有一個或多個空格,|表示或,\s+$表示結尾
}

11. 什么是原型

數組的push方法就是原型里的,數組是個對象,每個對象都有一個隱藏屬性__proto__,而數組的'proto'指向數組的原型Array.prototype,push方法就存在這里面可以直接引用(還有pop,slice,splice也是)

原型鏈

12. class(類)

  1. 類的聲明不會提升
  2. 舉例
class Rectangle {
    // constructor
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }
    // Getter
    get area() {
        return this.calcArea()
    }
    // Method
    calcArea() {
        return this.height * this.width;
    }
}
const square = new Rectangle(10, 10);

console.log(square.area);
// 100
  1. extends(繼承)
class Animal { 
  constructor(name) {
    this.name = name;
  }
  
  speak1() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  constructor(name, gender) {
    super(name)
    this.gender = gender
  }
  speak2() {
    console.log(this.name + ' barks. ' + this.gender);
  }
}

var d = new Dog('Mitzie', 'man');
d.speak2();

13. JS如何實現繼承

  1. extends(ES6)
    上面的extends
  2. 原型鏈(ES5)
function Animal(){
  this.body = '肉體'  //自身屬性
}
Animal.prototype.move = function(){}  

function Human(name){
  Animal.apply(this,arguments)  //繼承Animal的自身屬性
  this.name = name
}

Human.prototype.__proto__ = Animal.prototype

Human.prototype.useTools = function(){}  
//Human自己的原型屬性

14. 實現一個延時的同步函數

function execTime(t){
  let start = Date.now();
  //let start = new Date().getTime()
  //let start = + new Date();
  while(Date.now() - start < t){}
}

console.log(1)
execTime(3000)
console.log(2)

15. 實現異步函數

function execTime(t,callback){
  setTimeout(callback,t)
}

console.log(1)
execTime(3000,function(){
  console.log(3)
})
console.log(2)

16. 數組方法的使用

<h1>我要學 <span class="text">__</span></h1>
<ul class="box">
    <li>Java<input type="checkbox" value="Java"></li>
    <li>前端<input type="checkbox" value="前端"></li>
    <li>PHP<input type="checkbox" value="PHP"></li>
</ul>
<div>
    <input type="text" class="ipt"><button class="add">添加</button>
</div>
let box  = document.querySelector('.box')
let text = document.querySelector('.text')
let addBtn = document.querySelector('.add')
let input = document.querySelector('.ipt')

box.onclick = function (){
    text.innerText = [...box.querySelectorAll('input')].filter(checkbox=>checkbox.checked)
        .map(checkbox=>checkbox.value)
        .join(',')
}

addBtn.onclick = function () {
    let node = document.createElement('li')
    let checkbox = document.createElement('input')
    node.innerText = input.value
    checkbox.type = 'checkbox'
    checkbox.value = input.value
    node.appendChild(checkbox)
    box.appendChild(node)
}

17. 阻止事件冒泡

<h1>你選擇的是 <span class="text"></span></h1>
<button class="btn">點我</button>
<ul class="box">
    <li>菜單一</li>
    <li>菜單二</li>
    <li>菜單三</li>
</ul>
let box  = document.querySelector('.box')
let text = document.querySelector('.text')
let button = document.querySelector('.btn')
let input = document.querySelector('.ipt')


button.onclick = function (e) {
    box.style.display = 'block'
    e.stopPropagation()
}

document.onclick = function () {
    box.style.display = 'none'
}

box.onclick = function (e) {
    e.stopPropagation()
    text.innerText = e.target.innerText
}

18. 面試題,按屬性分組

一個數組里有很多項(對象),每一項都有label屬性,把所有label相同的項分為一個數組

function x(arr){
  let t = {}
  for(let i=0;i<arr.length;i++){
    if(t[arr[i].label]){
      t[arr[i].label].push(arr[i])
    }else{
      t[arr[i].label] = []
      t[arr[i].label].push(arr[i])
    }
  }
  return t
}

19. Array.sort面試題

排序

let l=[2,3,1]
l.sort()  //[1,2,3]

let a = [{age:3},{age:1},{age:2}]
a.sort(function(x,y){
  return x.age-y.age
})

20. Array.reduce

let a = [1,2,3]
a.reduce(function(sum,n){
  return sum+n  //6
},0)

第一個參數是一個函數,第二個參數是初始值傳給sum,會遍歷這個數組,n就是數組里的每一項,sum就是上一次return的數據

  • 面試題
    將一個數組里的所有小數組合并成一個大數組
let a = [[1,2,3],[4,5,6]]
a.reduce(function(sum,n){
  n.forEach(function(value,key){
    sum.push(value)
  })
  return sum
},[])

21. replace

let s = 'ad{{ra}}ds{{rd}}d'

function replaceTemp(s,object){
  for(let x in object){
    s = s.replace('{{'+x+'}}',object[x])
  }
  return s
}

replaceTemp(s,{ra:11, rd:12})

22. blur、focus事件不能冒泡

23. 判斷是不是數組

a instanceof Array
Array.isArray(a)

24. 將偽數組轉化為數組

let a = {0:'a',1:'b',length:2}
let b = Array.from(a)
//或者Array.prototype.slice.call(a)

25. 鼠標滑過出現浮層

onmouseover然后display: block,滑的快慢可以設置setTimeout,用e.offsetTop可以檢測元素距離頂部的位置

26. 面經

27. 函數面試題

  1. 滿足fn() === fn/fn.fn === fn
function fn(){
  fn.fn=fn;
  return fn
}
  1. 滿足obj.obj.obj...... === obj
obj = {}
obj.obj = obj

obj.obj.obj.obj.obj === obj  //true

27. 數組API

  • 面試題一

let students = [
{name:'1',score:86},
{name:'2',score:86},
{name:'3',score:86},
{name:'4',score:86},
]
用數組API計算總分、平均分、最高分、最低分

//總分
students.map(s=>s.score).reduce((s,n)=>s+n,0)
//平均分
students.map(s=>s.score).reduce((s,n)=>s+n,0)/students.length
//最高分
students.map(s=>s.score).sort()[student.length-1]
//最低分
students.map(s=>s.score).sort()[0]
  • 面試題二(sort)
    用sort對學生的姓名按字典序排序
let students = [{name: 'c'},{name: 'b'},{name: 'a'}]

stundents.sort((x,y)=>{
  if(x.name < y.name) {
    return -1
  }
  if(x.name > y.name) {
    return 1
  }
  return 0
})

28. Object面試題

  • 面試題1
let obj ={a:1,b:2,c:3}
//實現select函數,select(obj, ['a', 'c'])
//輸出 {a: 1, c: 3}
function select(obj,arr) {
    let n = {}
    arr.forEach(function(value){
        n[value] = obj[value]
    })
    return n
}

function select2(obj,arr) {
  let a = arr.reduce((o,n)=>{
    o[n]=obj[n]
    return o
  },{})
  return a
}

function select3(obj, arr) {
  return arr.reduce((ret, key) => 
    Object.assign(ret, { [key]: obj[key] }), {})
}


select(obj, ['a', 'c'])
//輸出 {a: 1, c: 3}
  • 面試題2

let p1 = {
'姓名': 'jirengu',
'性別': '男',
'年紀': 4,
}
寫一個函數,實現把p1變成
<dl><dt>姓名</dt><dd>jirengu</dd><dt>性別</dt><dd>男</dd><dt>年紀</dt><dd>4</dd></dl>

  1. 方法一
function renderTpl(p) {
    let html = '<dl>'
    for(let key in p){
        html += '<dt>' + key + '</dt>' + '<dd>'+ p[key] +'</dd>'
    }
    html += '</dl>'
    return html
}
  1. 方法二(Object.keys)
function renderTpl(p){
    return '<dl>'+ Object.keys(p).reduce((html,key)=>`${html}<dt>${key}</dt><dd>${p[key]}</dd>`,'') +'</dl>'
}
  1. 方法三(Object.entries)
function renderTpl(p){
    return '<dl>'+ Object.entries(p).reduce((html,key)=>`${html}<dt>${key[0]}</dt><dd>${key[1]}</dd>`,'') +'</dl>'
}
  • 面試題3
  1. 有學生列表,label代表每個學生的特點,假設每個學生的特點是唯一的,寫一個函數將學生按特點分類
let sundents = [{name: 'a', label: 'happy'}, {name: 'b', label: 'angry'}]
function mapper(students){
  let object = {}
  students.forEach(value=>{
    object[value.label] = value
  })
  return object
}
  1. 若學生的特點不是唯一,寫函數將學生按特點分組
function mapped2(students) {
  let object = {}
  students.forEach((value)=>{
    if(!object[value.label]){
      object[value.label] = []
    } 
    object[value.label].push(value)
  })
  return object
}
  • 面試題4
    寫一個函數,可以判斷兩個對象的值是否相等
function isObjectValueEqual(a, b) {
    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);

    if (aProps.length != bProps.length) {
        return false;
    }
    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i];
        if (a[propName] !== b[propName]) {
            return false;
        }
    }
    return true;
}

29. 寫函數去掉開頭的'$$'

let a = {$$x: 1, y: 2, z: [{$$a: 3. b: 4}]}
//把a轉為json"{"a":1,"b":2,"c":3}"

//判斷開頭的方法
str.substring(0,2) === '$$'

//函數,這個方法牛逼
const toJson = obj => {
  return JSON.stringify(obj, (key, n) => {
    if(key.substring(0,2) !== '$$'){
      return n
    }
  })
}
// n第一次是obj,接下來就是上一次return的東西,,然后這個函數會遍歷上一次return的東西

30. 正則面試題

用正則匹配以135或136或137開頭的11位手機號碼
/^13[567]\d{8}$/

31. 寫出輸出的內容

for(var i=0;i<5;i++){
    setTimeout(function(){
        console.log(1,i)
        if(i===5){
            i++
        }
    },0)
}
var n=0
for(var m=0;m<10000000;m++){
    n+=m
}
console.log(2,i)
// 2 5
// 1 5
// 1 6
// 1 6
// 1 6
// 1 6
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,042評論 0 2
  • 如何控制alert中的換行?\n alert(“p\np”); 請編寫一個JavaScript函數 parseQu...
    heyunqiang99閱讀 1,095評論 0 6
  • 這位剛來不久的阿姨做事真的特別很上心特別勤快,每一件事情都做的特別仔細,看到地上就主動去掃,每次撤臺都會先把垃圾清...
    words2閱讀 599評論 0 1
  • 關于生活關于活法!只愿意活的很認真很認真,不計較的一點都無所謂,該計較的必計較的一塵不染,原諒這放蕩不羈愛自由的赤...
    縱情嬉戲天地間閱讀 157評論 0 1
  • 年輕時沖動是一種美好的果斷 但一定要聽取中肯的意見 年輕時傲氣是一種自信的氣質 但一定不可以傲視的忽略 年輕時單純...
    滌生_7687閱讀 387評論 4 3