文章目录
一.函数防抖和函数节流
详见:
2021-06-20 函数防抖和函数节流的使用场景与方法
二.闭包
定义
闭包是利用作用域的嵌套,将局部变量进化成私有变量的一种环境
描述
函数和函数内部能访问到的变量共同组成了一个闭包
原理
1.计算机的回收机制
用过一次的东西先放在一个内存中不立即删掉,随时可以还原或再次使用,直到没有任何作用时清除
硬盘(存储空间):放进缓存区等待调用
内存(运行空间):直接删
*在闭包中,利用作用域的嵌套,触发计算机的垃圾回收机制
2.函数的定义作用域
函数所处的空间分为定义作用域和执行作用域
*规则:不管函数的执行作用域在哪,在函数执行时,都可以在函数内部,访问其定义作用域中的变量
形成闭包的三个条件
1.函数中嵌套一个函数
2.外层函数返回嵌套函数的函数名
3.内部嵌套函数引用外层的一个局部变量
示例
function foo(){
var local=1;
function bar(){//条件1:函数foo中嵌套一个函数bar
local++;
return local;//条件3:内部嵌套函数bar引用外层的一个局部变量local
}
return bar;//条件2:外层函数foo返回嵌套函数bar的函数名:bar
}
var func=foo();
console.log(func());
另一种写法
var func=foo();
console.log(func());
等价于
console.log(foo()());
而,
function foo(){
var local=1;
function bar(){//条件1:函数foo中嵌套一个函数bar
local++;
return local;//条件3:内部嵌套函数bar引用外层的一个局部变量local
}
return bar;//条件2:外层函数foo返回嵌套函数bar的函数名:bar
}
可以写成
function foo() {
var local = 1;
//条件1:函数foo中嵌套一个函数
return function() {//条件2:外层函数foo返回嵌套函数的函数名:匿名函数
return local++;//条件3:内部嵌套函数bar引用外层的一个局部变量local
}
}
这也是闭包:内嵌函数写成外层函数的return里的匿名函数
闭包的特点
闭包是连接函数内外的桥梁,可以读取函数内部的变量,这些变量始终保存在内存中,不会走函数调用后背系统回收,避免了全局命名变量空间的污染
由此,闭包的优缺点显而易见:
优点:
可以在函数外部调用函数内部的值,即在作用域外部改变作用域内部的数据
缺点:
浪费性能,消耗内存:造成内存的泄露
使用闭包的目的
用来间接访问一个变量,或者说:隐藏一个变量
(不想让该变量被别人直接访问,从而修改重要数据,而局部变量让人无法访问也不是我们想要的)
闭包的两个应用场景
1.循环中的事件获取循环每次执行的计数器
for循环中存在调用自增变量i的函数时,详见:
2021-06-11 解决异步问题:for循环中的点击事件无法获取自增中的i
2.给内置方法的缓存调函数传参
例子:给setTimeout的回调函数传参
// 出现问题:
// setTimeout(function(a){
// console.log(a);//undefined
// },2000)
// 或者:
// setTimeout(fn(10), 2000);
// function fn(a) {
// console.log(a);//未等待2s
// }
//解决方法:使用闭包
function fn(a) {
return (function() {
console.log(a)
})
}
setTimeout(fn(10), 2000);
三.原型链
什么是原型链?
原型链:就是实例对象和原型对象之间的链接,每一个对象都有原型,原型本身又是对象,原型又有原型,以此类推形成一个链式结构.称为原型链
1.对象的__proto__
1.1.万物皆对象,每个对象都有一个属性,这个属性叫做隐式原型(__proto__)
1.2.一个对象的隐式原型指向其构造函数的原型链属性
(即p.__proto__===Person.prototype)
1.3.这种指向使对象的实例可以访问到原型上属性与方法
访问原型上的say方法:p.__proto__.say();
2.函数的prototype
2.1.万物皆对象,函数也是一种对象,凡对象必有__proto__属性
2.2.函数还有自己的特有属性:显式原型(prototype)
2.3.prototype常当成指针使用,指向对象类型的数据
2.4.原型对象prototype包含将来使用函数构造出来的属性和方法
2.5.原型对象prototype的属性constructor可以指回构造函数
(即Person.prototype.constructor === Person)
3.构造函数&原型&实例的关系
4.实例对象中,是否有指针,指向构造函数的原型
- 方法:isPrototypeOf()
- 关键字:instanceof
用法:
function Box() {}
var b = new Box();
console.log(b instanceof Box); //true
console.log(Box.prototype.isPrototypeOf(b)); //true
含义:实例对象b中有指针指向构造函数Box的原型Box.prototype