一、防抖与节流
1.函数防抖debounce
1.1 作用: 多用于搜索框,当其被疯狂、高频地点击,这个函数最后只会被执行一次。
1.2 实现思路: 每次点击都先清除之前的timer,然后重新设定定时器,以确保fn只执行一次。
const debounce = (fn, duration) => {
let timer = null
let fns = () => {
clearTimeout(timer)
timer = setTimeout(fn, duration)
}
return fns
}
2.函数节流throttle
2.1 作用: 多用于具有倒计时功能的按钮,当点击发送按钮后,开始进行倒计时,这期间无法发送,当倒计时结束后,可再次发送。换句话说当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
2.2 实现思路: 在发送后开始倒计时,倒计时结束后清除timer,这期间所有请求全部 return false。
const throttle = (fn, duration) => {
let timer = null
let fns = () => {
if (timer) {
return false
} else {
timer = setTimeout(() => {
timer = null
}, duration)
return fn()
}
}
return fns
}
二、执行顺序
async function async1(){
console.log('async1 start')
await async2() // await执行完后,会让出线程。async标记的函数会返回一个Promise对象
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
}, 0)
async1();
new promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')
答案:
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout
类似:
async function test(){
console.log(1)
await demo()
console.log(2)
}
test()
function demo(){
console.log(3)
}
Promise.resolve().then(res => {
console.log(4)
})
console.log(5)
答案:
1 3 5 2 4
参考:[www.cnblogs.com/geyouneihan…]
三、深度克隆
1.
JSON.parse(JSON.stringify(obj))
2.
function deepClone(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj
}
const target = Array.isArray(obj) ? [] : {}
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
target[key] = deepClone(obj[key])
} else {
target[key] = obj[key]
}
}
}
return target
}
四、闭包
1
function add(n){
let num = n
return function addTo(x){
return x + num
}
}
addTwo = add(2)
console.log(add(2)) // f addTo(x){ return x + num }
console.log(addTwo(5)) // 7
console.log(add(2)(5)) // 7
2
for (var i = 0; i<5; i++) {
setTimeout(() => {
console.log(i) // 5 5 5 5 5
}, 500)
}
for (var i = 0; i<5; i++) {
(j => {
setTimeout(() => {
console.log(j) // 0 1 2 3 4
}, 500)
})(i)
}
for (let i = 0; i<5; i++) {
setTimeout(() => {
console.log(i) // 0 1 2 3 4
}, 500)
}
五、引用数据类型的值是指向堆的指针
javascript中的数据分为:
基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)
复杂的数据类型(也称作引用数据类型Object)
let a = {n: 1}
let b = a
a.x = a = {n: 2}
console.log(a)
console.log(a.x)
console.log(b.x)
解答:
a = {n: 1, x: undefined} 点的优先级要高于等号(所以a.x没定义)
在js的运算中“.”和"="运算符同时出现,会先执行"."运算。因此,赋值顺序被改变了,是先给a.x赋值,再给a赋值
a = {n: 2} 赋值
{n: 1, x: undefined}中x指向{n: 2}
b = {n: 1, x: {n: 2}}
可以简化成:
// a.x = a = {n: 2}
a.x // undefined
a.x = {n: 2}
a = {n: 2}
六、作用域
var a = 10
;(function(){ // 不写 ; 时要注意(function()())前要加 ; 防止连在一起报错
console.log(a) // var a 变量提升,undefined 。如果作用域内没有定义就往上一层作用域找,再没有就再往上一层。。。全局。
a = 5
var a = 20
console.log(a) // 10
})()
// undifined 20
七、while
while语句先判断再执行运算,条件为true一直执行,false就停止(0也是false)
let a = 1
while (--a) {}
console.log(a) // 0
let b = 1
while (b--) {}
console.log(b) // -1