JS基础学习——必会题汇总

67 阅读4分钟

以下代码输出什么?

let a = 1

function fn1(){
  function fn2(){
    console.log(a)
  }
  function fn3(){
    let  a = 3
    fn2()
  }
  let a = 2
  return fn3
}

let  fn = fn1()
fn() 
答案: 2
执行fn2时往上级作用域fn1中找a,由于let a = 2已经执行,所以a此时的状态是2。

递归实现斐波那契数列

function fib(n) { if(n===1 || n===2) return 1 return fib(n-1)+fib(n-2) }

subStr和subString的区别

相同点是都不改变原数组,当只传一个参数时没有区别。
传入第二个参数时,substr是从起始点截取某个长度的字符串
subStr(start, num) √
而substring是截取2个位置之间的字符串
subString(start, end)

splice与slice区别

splice会改变原数组,而slice不会,并且splice会导致数组塌陷。
splice(start,num,insert) 位置开始,删几个,插入什么 √
slice(start,end) 从哪到哪开始删

字符串拼接的常用方法

str1.concat(' ').concat(str2)
str1 + str2
模板字符串 `${str1} ${str2}`

把类数组对象arrayLike转换成数组

Array.from(arrayLike)
\[...arrayLike\]

写一个reverseStr函数,实现字符串逆序输出

return  str.split{''}.reverse().join('')

实现数组arr从小到大排序

注意:sort会改变原数组

arr.sort((a, b) => a-b>0? 1 : -1)<br>
甚至可以简写成
arr.sort((a, b) => a-b)

实现数组arr中的对象,以age从小到大排序

arr.sort((v1, v2) => v1.age-v2.age)

实现fn函数,参数为数组,返回数组中正数的平方和

我的写法:

const fn = (arr) => {
  let res = 0;
  for(let val of arr) {
    if(val > 0) res += val**2
  }
return res
}

简单写法:

const fn = arr => arr.filter(v => v>0).reduce((res, v) => res + v**2 , 0)

写一个函数将对象的属性和值拼接为key1=value1&key2=value2形式的字符串

我用的for-in循环没有这个Object.keys()方便

function traverse(obj) {
  return Object.keys(obj).map(key => `${key}=${obj[key]}`).join('&')
}

对象转换为JSON字符串&&JSON格式字符串转换为对象

JSON.stringify(obj)
JSON.parse(str)

清空一个数组的两种写法

arr = [] 本质上是创建一个新的空数组,让arr指向新的空数组
arr.length = 0 本质上是对原数组操作,让原数组变成空数组

以下代码输出什么

function inc(n){
 console.log(++n)
}
let n = 10
inc(n)
console.log(n)
11 10 因为inc没有返回值。即使去掉console.log, n在函数内部的变化也不会影响外面的n,因为没有返回值。

forEach()和map()的区别

forEach() 方法不会返回执行结果,而是修改原来的数组 map() 方法会得到一个新的数组并返回

深拷贝的简单写法

function deepCopy(src) {
    return JSON.parse(JSON.stringify(src))
}

把字符串中的div标签替换成span标签

str.replace(/(<\/?)div(.*?>)/g, '$1span$2')

匹配一个字符,这个字符可以是'abc'中的任何一个

/[abc]/

匹配字符串"[abc]"

/\[abc\]/

以1为开头的长度为11位且全为数字的字符串

/^1\d{10}$/.test(str)

验证用户输入是否为合法密码。参数为字符串,返回值为布尔值

  • 密码长度6~20位
  • 密码只能是大小写字母、数字、下划线、$
  • 大写、小写、数字、下划线、$至少包含两种
function validPassword(rawInput) {

if(!/^[\w\d$_]{6,20}$/.test(rawInput)) return false
if (/(^[a-z]+$)|(^[A-Z]+$)|(^\d+$)|(^_+$)|(^\$+$)/.test(rawInput))
return false
else  return true
}

注意定时器是自动执行的,只有函数内放定时器才是调用后执行

原型链的顶端 Object.prototype

Array.__proto__.constructor
ƒ Function() { [native code] }
Function.__proto__.constructor
ƒ Function() { [native code] }
Function.prototype.__proto__.constructor
ƒ Object() { [native code] }
Object.__proto__.construtor
undefined

如何判断某属性是对象的自有属性

记得括号里加引号

[1,2].hasOwnProperty('sort')
false
[1,2].__proto__.hasOwnProperty('sort')
true
Array.hasOwnProperty('sort')
false
Array.prototype.hasOwnProperty('sort')
true

继承时this的指向问题

image.png

写一个函数 orderBy ,实现数组按姓名、年纪、任意字段按照设置对升降序排序

let users = [  { name: "Bob", age: 20, company: "Baidu" },  { name: "Cat", age: 18, company: "Alibaba" },  { name: "Ann", age: 19, company: "Tecent" }]

console.log( users.sort(orderBy('company', 'asc')) )  // company字段 以升序(从小到大)排序
console.log( users.sort(orderBy('age', 'desc'))  )     //age 字段以降序(从大到小)排序
const orderBy = (field, order = 'asc') => (v1, v2) => {
if (order === 'asc') return v1[field] > v2[field] ? 1: -1
if (order === 'desc') return v1[field] > v2[field] ? -1: 1
}

两种绑定事件的方法

方法一:

$node.onclick = function() {...}

只能绑定一个事件监听函数,如果再次设置 .onclick,则会覆盖之前的绑定。因为本质上是给一个对象的onclick属性重新赋值;只能在事件冒泡阶段监听。

方法二:

document.body.addEventListener('click', function(){...})

可以针对click事件绑定多个事件监听函数;还有第三个参数,如果不设置,默认是false,表示在事件冒泡阶段监听。如果设置为true,表示在捕获阶段监听。

写一个函数 isAndroid,用来判断系统是不是安卓,返回 true/false

const isAndroid = () => /android/i.test(navigator.userAgent)

如何mock数据

 手写server来mock数据  使用阿里团队的rap2来mock数据 使用大搜车前端团队的easy-mock (easy-mock.com/)来mock数据 使用Mock.js 来mock数据

loader 和 plugin 的区别

 loader 用于对模块的源代码进行转换
 loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript
 loader 甚至允许你直接在 JavaScript 模块中 import CSS文件
 plugin 用于解决loader无法实现的其他事,比如打包优化、压缩等

css-loader 能接收并处理css文件,并对css语法进行解析
style-loader 用于把css 注入到DOM
file-loader用于把里通过 import/require 引入的文件导出到目标文件夹,并且得到新的文件路径
在使用多个loader时顺序很重要,数组的最后一个最先接收并处理文件

关于HMR

模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面
模块热替换能保留在完全重新加载页面时丢失的应用程序状态
只更新变更内容,以节省宝贵的开发时间。
HMR 只能在开发环境中使用
调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式

关于 treeshaking

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)
tree shaking 它依赖于ES2015模块语法的静态结构,即import和export
tree shaking 能减小代码体积,是性能优化的一种手段

参考资料:xiedaimala.com/courses/579…