基本函数的表达方式
function fun(){
let a=10;
return a;
}
let res=fun()
console.log(res);//10
只能得到一个返回值的结果并不能去对函数里的变量a进行任何操作(访问变量)
image.png闭包
(1)闭包的第一种方式,return返回一个匿名函数,并return返回值
按理说呢,a是函数内部的变量,我们是不能在外部访问的,但是这里匿名函数相当于延续的变量a的生命周期,并且当我们多次运行res变量的时候,我们得到函数执行累加的返回结果
image.png image.png闭包 : 闭包就是通过某种方式获取(函数)内部的变量,然后暴露到函数的外部,并且在将来的某个节点还可以继续操作这个变量。
优点:可以防止污染我们的全局作用域
缺点:会导致一个内存库泄露的问题
(2)闭包的第二种方式值 希望用到函数内部的变量,但是又不想return,应该怎么办?
加入函数外部有一个变量对象 就需要给这个变量临时添加方法,一个get()方法 并且对应一个set()方法,在get()方法里获取变量(直接return返回结果),在到set()的方法里用传参再接收参数就可以了。
外部调用就不需要返回值了,直接调用函数就可以访问到函数内部的变量了,如:
let obj = {}
function fun() {
var a = 10;
obj.get = function () {
return a;
}
obj.set = function (v) {
a = v;
}
}
fun();//调用
console.log(obj.get());//10
image.png
当我们调用obj.get()时并不知道get里面的有a的变量,再看obj={}的代码其实是也只是个空的对象,但确实obj.get()能拿到值为10,也就是说函数内部处理好了get()和set()的方法,所以说,闭包会产生一种鬼魅的幽灵变量,你感觉不到它的存在,但是它确实存在着
(3)闭包的第三种存在方式,(举例是vue框架中的用法)
var data = {
name: '',
iphone: ''
}
//属性劫持
for (let key in data) {
console.log(key);
}
key的返回结果
image.png
溢出问题
var data = {
name: '',
iphone: ''
}
//属性劫持
for (let key in data) {
// console.log(key);//name iphone
//解决死循环的问题,临时添加一个变量接收data[key],这个变量在函数里只会执行一次,所以不会死循环
let value = data[key];
Object.defineProperty(data, key, {
get() {
// return data[key];
},
set(v) {
console.log('对应的DOM更新', "----");//死循环,内存溢出
data[key] = v;
console.log('对应的DOM更新');
}
})
}
image.png
var data = {
name: '',
iphone: ''
}
//属性劫持
for (let key in data) {
// console.log(key);//name iphone
//解决死循环的问题,临时添加一个变量接收data[key],这个变量在函数里只会执行一次,所以不会死循环
let value = data[key];
Object.defineProperty(data, key, {
get() {
// return data[key];
return value;
},
set(v) {
// (1)
// console.log('对应的DOM更新', "----");//死循环,内存溢出
// data[key] = v;
value = v;
console.log('对应的DOM更新');
}
})
}
image.png
网友评论