js
1.函数防抖节流
//防抖
function debounce(func, wait) {
let timeout;
return function () {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
func.apply(this, arguments)
}, wait)
}
}
//节流
function throttle(func, wait) {
let timeout;
return function () {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(this, arguments)
}, wait)
}
}
}
function say() {
console.log(‘hi haha‘)
}
document.onmousemove = debounce(say, 1000)
document.onmousemove = throttle(say, 1000)
2.闭包
没有被引用的闭包会被自动回收,但还存在全局变量中,则依然会内存泄漏。 在 JavaScript 中,根据词法作用域的规则,内部函数总是可以访问其外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,我们就把这些变量的集合称为闭包。
比如外部函数是 foo,那么这些变量的集合就称为 foo 函数的闭包。
function getNum() { let n = 1 return function() { n++ } } getNum() // 2 getNum() // 3 getNum() // 4 getNum() // 5
3.new操作符
const New = function (Fn) {
let obj = {}, // 创建空对象
arg = Array.prototype.slice.call(arguments, 1)
obj.__proto__ = Fn.prototype // 将obj的原型链__proto__指向构造函数的原型prototype
obj.__proto__.constructor = Fn // 在原型链 __proto__上设置构造函数的构造器constructor,为了实例化Fn
Fn.apply(obj, arg) // 执行Fn,并将构造函数Fn执行obj
return obj // 返回结果
}
function Persen(name) {
this.name = name
}
console.log(New(Persen, ‘hahha‘)) // Persen {name: "hahha"}
4.函数柯里化
const curry = fn => { if (typeof fn !== "function") { throw Error("No function provided") } return function curriedFn(...args) { if (args.length < fn.length) { return function () { return curriedFn.apply(null, args.concat([].slice.call(arguments))) } } return fn.apply(null, args) } } function add(a, b, c) { console.log(a + b + c) } let ad = curry(add) ad(1)(1)(1) // 复用几次取决于有多少参数
5.简单的深拷贝-递归实现
function copy(obj) { let result = Array.isArray(obj) ? [] : {} for (let key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === ‘object‘) { result[key] = deepCopy(obj[key]) // 递归复制 } else { result[key] = obj[key] } } } return result } let a = { name: ‘lj‘ }, b = copy(a) b.name = ‘lc‘ console.log(a, b) // {name: "lj"} {name: "lc"}
6.js运行机制
宏任务(macro-task):整体代码script、setTimeOut、setInterval 微任务(mincro-task):promise.then、promise.nextTick(node) 需要注意的是new Promise是会进入到主线程中立刻执行,而promise.then则属于微任务 function add(x, y) { console.log(1) setTimeout(function() { // timer1 console.log(2) }, 1000) } add() setTimeout(function() { // timer2 console.log(3) }) new Promise(function(resolve) { console.log(4) setTimeout(function() { // timer3 console.log(5) }, 100) for(var i = 0; i < 100; i++) { i == 99 && resolve() } }).then(function() { setTimeout(function() { // timer4 console.log(6) }, 0) console.log(7) }) console.log(8) 执行结果 //1,4,8,7,3,6,5,2
7.从输入URL到页面显示的过程
1. 发送URL,请求IP地址 2. TCP三次握手 第一次握手:建立连接,第二次握手:服务器收到SYN报文段,第三次握手:客户端收到SYN+ACK报文段 3.服务器响应200 4.生成Render Tree 5.渲染页面