手写new、call、apply、bind、防抖和节流,促进对其理解
1. new
(() => {
function MyNew(fn, ...args) {
if (!(fn instanceof Function)) {
throw new TypeError('not a constructor')
}
const obj = {}
obj.__proto__ = fn.prototype
const retult = fn.call(obj, ...args)
return typeof result === 'object' ? retult : obj
}
function Person(age, name) {
this.age = age
this.name = name
}
Person.prototype.hallo = function () {
console.log(`name:${this.name},age:${this.age}`)
}
console.log('----------------------手写new-----------------------')
MyNew(Person, 18, 'coco').hallo()
})();
2. call
(() => {
Function.prototype.myCall = function (content = window, ...args) {
if (typeof this !== 'function') {
throw new TypeError('not a function')
}
content.fn = this
const result = content.fn(...args)
delete content.fn
return result
}
function test(age) {
console.log(`name:${this.name},age:${age}`)
}
console.log('----------------------手写call-----------------------')
test(18)
test.call({
name: 'coco'
}, 18)
delete Function.prototype.myCall
})();
3. apply
(() => {
Function.prototype.myApply = function (content = window, args) {
if (typeof this !== 'function') {
throw new TypeError('not a function')
}
content.fn = this
const result = content.fn(...args)
delete content.fn
return result
}
function test(age1, age2) {
console.log(`name:${this.name},age:${age1},age2:${age2}`)
}
console.log('----------------------手写apply-----------------------')
test(18, 19)
test.myApply({
name: 'coco'
}, [18, 19])
delete Function.prototype.myCall
})();
4. bind
(() => {
Function.prototype.myBind = function (content, ...defaultArgs) {
if (typeof this !== 'function') {
throw new TypeError('not a function')
}
const fn = this
return function F(...args) {
const as = [...defaultArgs, ...args]
if (this instanceof F) {
return new fn(...as)
} else {
return fn.apply(content, as)
}
}
}
function test(age1, age2) {
console.log(`name:${this.name},age:${age1},age2:${age2}`)
}
console.log('----------------------手写bind-----------------------')
test(18, 19)
const boundTest = test.bind({
name: 'coco'
}, 18)
boundTest(19)
delete Function.prototype.myBind
})();
5. 防抖
function debounce(fn, delay) {
let timer = null
return function (...args) {
timer && window.clearTimeout(timer)
timer = window.setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
var testDebounce = {
clickTime: 0,
runTime: 0
}
function willDebounceClick() {
this.runTime++
console.log(`run time ${this.runTime}`)
}
function onBtnClick() {
this.clickTime++
console.log(`click time ${this.clickTime}`)
}
console.log('----------------------手写debounce-----------------------')
var btn = document.getElementById('debounceBtn')
btn.addEventListener('click', debounce(willDebounceClick.bind(testDebounce), 1000))
btn.addEventListener('click', onBtnClick.bind(testDebounce))
6. 节流
function throttle(fn, timeScale = 100) {
let prev = new Date()
return function (...args) {
const now = new Date()
if (now - prev >= timeScale) {
fn.apply(this, args)
prev = now
}
}
}
var throttleTest = {
scrollTime: 0,
throttleScrollTime: 0
}
var scrollDiv = document.getElementById('scrollDiv')
function willThrottleScroll() {
this.throttleScrollTime++
console.log(`11111111111111 throll run time:${this.throttleScrollTime}`)
}
function onScroll() {
this.scrollTime++
console.log(`scroll run time:${this.scrollTime}`)
}
console.log('----------------------手写节流-----------------------')
window.addEventListener('scroll', throttle(willThrottleScroll.bind(throttleTest), 300))
window.addEventListener('scroll', onScroll.bind(throttleTest))
相关代码