【精简版】前端面试知识点(代码篇)

446 阅读9分钟

JS

运算符

^=:a^=b等价于a = a^b,其中^是位异或运算,即将a与b的对应位进行异或运算同为0或者同为1时,对应位结果为0,否则为1

JS字符串操作

  • charAt(索引位置):返回指定位置的字符
  • charCodeAt(索引位置):返回指定位置字符的Unicode编码
  • fromCharCode(字符编码):将Unicode编码转为一个字符,连续多个返回字符串
  • concat(a,b,...,n):用于连接两个或多个字符串
  • indexOf():检索字符串,返回字符串开始位置的索引
  • lastIndexOf():从后向前搜索字符串,返回索引值
  • replace():替换与正则匹配的字符串
  • split('分隔字符'):用指定的字符分割字符串,返回一个数组,原来不变
  • trim():删除字符头尾的空白符,不改变原字符串
  • toString():返回一个表示 String 对象的值

大小写转换

  • toLowerCase():大写->小写,不改变原字符串
  • toUpperCase():小写->大写,不改变原字符串
  • toLocaleLowerCase():根据本地主机的语言环境把字符串转换为小写,不改变原字符串
  • toLocaleUpperCase():根据本地主机的语言环境把字符串转换为大写,不改变原字符串

截取字符串

  • substr(a,b)截取字符串,从a索引开始,截取b个字符,将截取的字符返回,不改变原来的字符串。
  • substring(a,b)截取字符串,从索引a到索引b,不包括索引b的字符。返回截取字符。
  • slice(a,b)截取字符串,从索引a开始到索引b(不包括),可接受参数为负数,从后往前截取。

JS数组操作

  • sort(参数):对数组排序,会修改原数组,默认升序
  • splice:splice(start,length,item)删,增,替换数组元素,返回被删除数组,无删除则不返回
  • reverse:颠倒数组元素顺序
  • copyWithin(t,s,e):从数组的指定位置拷贝元素到数组的另一个指定位置中,不改变原数组长度。
  • fill:用一个元素填充原来的数组
  • concat():用于连接两个或多个数组,返回新的数组,原来的不变
  • join(分隔符):将数组中所有元素以参数作为分隔符转换成一个字符串,默认为逗号
  • slice(a,b)截取数组,从索引a开始到索引b(不包括),返回选定的元素,不改变原数组
  • some(function(c,i,arr), thisValue):用于检测数组中的元素是否满足指定条件(函数提供),不对空数组检测,也不改变原数组。

遍历数组

  • map(function(c,i,arr), thisValue):返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
  • filter(function(c,i,arr), thisValue):创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,不对空数组检测,也不改变原数组。
  • forEach(function(c,i,arr), thisValue):用于调用数组的每个元素,并将元素传递给回调函数,对空数组不执行,不会返回新的数组
  • every(function(c,i,arr), thisValue):用于检测数组所有元素是否都符合指定条件,依次执行数组的每个元素。如果数组中检测到有一个元素不满足,则返回 false ,且剩余的元素不会再进行检测。如果所有元素都满足条件,则返回 true。不对空数组进行检测,不改变原数组。

模仿栈,改变原数组

  • pop():删除数组的最后一个元素并返回删除的元素
  • push():向数组的末尾添加一个或更多元素,并返回新的长度
  • shift():把数组的第一个元素从其中删除并删除的值,空即为undefined
  • unshift():向数组开头添加元素,并返回新的长度

DOM相关操作

scrollIntoView()

scrollIntoView()方法将调用它的元素滚动到浏览器窗口的可见区域,页面滚动才生效

1行JS代码实现常用功能

  • 将值转换为数组
// js
const castArray = (value) => (Array.isArray(value) ? value : [value]);
// ts
const castArray = <T,_>(value: T | T[]): T[] => (Array.isArray(value) ? value : [value]);

扁平数组转树形结构

相关资料:扁平数组转树形结构的几种实现

object的方法

(1) Object.is(value1, value2):用于判断两个值是否相同的方法。

  • 参数:value1:要比较的第一个值。value2:要比较的第二个值。
  • 返回值:一个布尔表达式,指示两个参数是否具有相同的值。

(2) Object.assign(target, ...sources):方法用于将所有可枚举的自身属性从一个或多个源对象复制到目标对象,浅拷贝。

  • 参数:target:目标对象——应用源属性的对象,修改后返回。sources:源对象——包含你要应用的属性的对象。
  • 返回值:修改后的目标对象。

(3) Object.entries(obj) ES8的Object.entries是把对象转成键值对数组, [key, value] 对的数组。

  • 参数:obj:要返回其自己的可枚举字符串键属性 [key, value] 对的对象。
  • 返回值:给定对象自己的可枚举字符串键属性 [key, value] 对的数组。 Object.fromEntries则相反,是把键值对数组转为对象

(4) Object.values() 方法返回给定对象自己的可枚举属性值的数组,其顺序与 for...in 循环提供的顺序相同。 语法:Object.values(obj) 参数:obj:要返回其可枚举自身属性值的对象。返回值:包含给定对象自己的可枚举属性值的数组。

(5) Object.prototype.hasOwnProperty() hasOwnProperty() 方法返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性。 如果指定的属性是对象的直接属性,则该方法返回 true — 即使值为 null 或未定义。如果该属性是继承的或根本没有声明,则返回 false。 语法:hasOwnProperty(prop) 参数:prop:要测试的属性的字符串名称或符号。 返回值:如果对象将指定的属性作为自己的属性,则返回true;否则为false。

(6) Object.keys():Object.keys() 方法用于返回给定对象自己的可枚举属性名称的数组,以与普通循环相同的顺序迭代。

  • 语法:Object.keys(obj)
  • 参数:obj:要返回可枚举自身属性的对象。 返回值:表示给定对象的所有可枚举属性的字符串数组。

(7) Object.prototype.toString():toString() 方法返回一个表示对象的字符串。当对象将被表示为文本值或以期望字符串的方式引用对象时,将自动调用此方法 id。默认情况下,toString() 方法由从 Object 继承的每个对象继承。 语法:toString() 返回值:表示对象的字符串。

(8) Object.freeze():方法冻结一个对象,这意味着它不能再被更改。冻结对象可防止向其添加新属性,防止删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。它还可以防止其原型被更改。 语法:Object.freeze(obj) 参数:obj:要冻结的对象。返回值:传递给函数的对象。

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。) 语法:const me = Object.create(person); 参数: proto:新创建对象的原型对象。 propertiesObject 可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。 返回值 一个新对象,带着指定的原型对象和属性

JS属性操作

添加对象属性:变量名.自定义属性名 = 属性值
删除对象属性:delete  变量名.自定义属性名;
添加对象方法:和添加属性地方法类似
修改属性值:用新的属性替换旧的属性
获取对象的属性名和值:代码如下

dataObj = {
    name : "gao",
    age : 26
};
for(var d in dataObj) {
    var d; // 属性名name
    var dataObj[d]; //属性值gao
}

数组去重

(1) 利用Set()+Array.from()

  • Set对象:是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即Set中的元素是唯一的。
  • Array.from():对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
const result = Array.from(new Set(arr))
console.log(result)  // [ 1, 2, 'abc', true, false, undefined, NaN ]` 

(2) 利用两层循环+数组的splice方法:通过两层循环对数组元素进行逐一比较,然后通过splice方法来删除重复的元素。此方法对NaN是无法进行去重的,因为进行比较时NaN !== NaN。

function removeDuplicate(arr) {`
    let len = arr.length
    for (let i = 0; i < len; i++) {`
        for (let j = i + 1; j < len; j++) {
            if (arr[i] === arr[j]) {
            arr.splice(j, 1)`
len-- // 减少循环次数提高性能`

j-- // 保证j的值自加后不变`
}
}
  }
   return arr
}

(3) 利用数组的indexOf方法

(4) 利用数组的includes方法

(5) 利用数组的filter()+indexOf()filter方法会对满足条件的元素存放到一个新数组中,结合indexOf方法进行判断。

function removeDuplicate(arr) {
    qreturn arr.filter((item, index) => {
        return arr.indexOf(item) === index
    })
}

注意:这里的输出结果中不包含NaN,是因为indexOf()无法对NaN进行判断,即arr.indexOf(item) === index返回结果为false。

(6) 利用Map(): Map对象是JavaScript提供的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,然后结合has()和set()方法判断键是否重复。

Map 对象: 用于保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。

function removeDuplicate(arr) {
    const map = new Map()
    const newArr = []
    arr.forEach(item => {
        if (!map.has(item)) {  
            // has()用于判断map是否包为item的属性值`
            map.set(item, true )  
            // 使用set()将item设置到map中,并设置其属性值为true
            newArr.push(item)
        }
    })
    return newArr
}

注意: 使用Map()也可对NaN去重,原因是Map进行判断时认为NaN是与NaN相等的,剩下所有其它的值是根据 === 运算符的结果判断是否相等。

(7) 利用对象:其实现思想和Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。

function removeDuplicate(arr) {
    const newArr = []
    const obj = {}
    arr.forEach(item => {
        if (!obj[item]) {
            newArr.push(item)
            obj[item] = true
        }
    })
    return newArr
}

数组编平化

(1) 调用 ES6 中的 flat 方法

ary = arr.flat(Infinity)
console.log([1, [2, 3, [4, 5, [6, 7]]]].flat(Infinity))

2、普通递归

let result = []
let flatten = function (arr) {
  for (let i = 0; i < arr.length; i++) {
    let item = arr[i]
    if (Array.isArray(arr[i])) {
      flatten(item)
    } else {
      result.push(item)
    }
  }
  return result
}

let arr = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(arr))

3、利用 reduce 函数迭代

function flatten(arr) {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur)
  }, [])
}

let arr = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(arr))

4、扩展运算符

function flatten(arr) {
  while (arr.some((item) => Array.isArray(item))) {
    arr = [].concat(...arr)
  }
  return arr
}

let arr = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(arr))

url参数提取并保存在对象中

例子url = '?name=zhangsan&sex=man&age=12’

思路:通过"?“将url地址分为俩部分,截取后面的参数部分,然后将后面的字符串通过”&“进行分割,返回一个数组,然后遍历数组,将数组中的每一项通过”="进行分割,此时返回的数组只有俩项,然后将其以key:value的形式存入对象中。

代码如下

var url = '?name=zhangsan&sex=man&age=12';
function fun(url) {
    var newUrl = url.split("?")[1].split("&");
    var obj = {};
    for(var i=0; i<newUrl.length; i++){
        var arr = newUrl[i].split("=");
        obj[arr[0]] = arr[1];
    }
    return obj;
}   
console.log(fun(url));

防抖函数

function debounce(fn,delay){
    let timer;
    return funntion(){
        let me=this;
        tiemr && clearInterval(timer);
        timer=setTimeout(function(){
            fn.call(me);
        },delay)
    }
}