Github:https://github.com/ChenMingK/WebKnowledges-Notes
推荐在线阅读:https://www.kancloud.cn/chenmk/web-knowledges/1077426
文章目录
实现 call、apply、bind
实现 call
首先要明白 call 是干什么的:call 方法在使用一个指定的 this 和若干个指定的参数值的前提下调用某个函数或方法
① 如何改变 this 指向?
- 将函数设置为对象的属性
- 执行该函数
- 删除该函数
delete 运算符可以删除对象的属性,但是不能删除一个变量或者函数
② 如何把参数传给要执行的函数并使其执行,且传入的参数个数是不确定的?
- 运用 rest 运算符,或者使用 arguments 对象
Function.prototype.call2 = function (context, ...args) {
// 首先要获取调用 call 的函数,用 this 可以获取
context.fn = this
context.fn(...args)
delete context.fn // delete 删除对象的属性
}
let foo = {
value: 1
}
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
bar.call2(foo, 'kevin', 18) // kevin 18 1
实现 apply
和 call 基本一样,只是参数变为数组了而已
Function.prototype.apply2 = function (context, arr) {
// 首先要获取调用 call 的函数,用 this 可以获取
context.fn = this
context.fn(...arr)
delete context.fn // delete 删除对象的属性
}
let foo = {
value: 1
}
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
bar.apply2(foo, ['kevin', 18]) // kevin 18 1
实现 bind
首先也是搞明白 bind 的作用是什么:bind() 方法会创建一个新函数,当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,传递参数时,
可以在 bind 时传递部分参数,调用时又传递其余参数
完整的 bind 还考虑了:一个绑定函数也能使用 new 操作符创建对象:这种行为就像把原函数当成构造器。
提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
下面的代码只实现 bind 的部分功能:
Function.prototype.myBind = function (context, ...args1) {
if (typeof this !== 'function') {
// 只允许函数调用 bind 方法
throw new Error('Error')
}
let self = this
let firstArgs = args1
return function (...args2) {
return self.apply(context, firstArgs.concat(args2))
}
}
更完整的 bind 实现参考:https://github.com/mqyqingfeng/Blog/issues/12
Promise 封装原生 AJAX
let AJAX = function (url) {
let promise = new Promise(function (resolve, reject) {
let XHR = new XMLHttpRequest()
XHR.open('get', url, false) // false:异步 true:同步
XHR.onreadystatechange = handler
XHR.send()
function handler() {
if (XHR.readyState !== 4) {
return
}
if (XHR.status === 200) {
resolve(XHR.response)
} else {
reject(new Error(XHR.statusText))
}
}
})
return promise
}
XMLHttpRequest 的一些属性和方法可参考:AJAX 整理
函数节流、防抖 + immediate版
参考 https://github.com/mqyqingfeng/Blog/issues/22
防抖和节流的作用都是防止函数多次调用,区别在于,假设一个用户一直触发这个函数,且每次触发函数的时间间隔小于 wait,
防抖的情况下只会调用一次,而节流的情况会每隔一定时间调用函数
// 防抖
function debounce(fn, wait) {
let timer = 0
return function (...args) {
if (timer) clearTimeout(timer) // 清除并重新设置定时任务
timer = setTimeout(() => {
fn.apply(this, args)
}

本文探讨JavaScript面试中的常见问题,包括手写call、apply、bind的实现,Promise封装AJAX,函数节流、防抖,函数柯里化,深浅拷贝,字符串和数组操作等实战技巧。通过实例解析,帮助你巩固JavaScript基础和提升面试技巧。

9597

被折叠的 条评论
为什么被折叠?



