JavaScript 作用域与闭包

本文内容学习于:后盾人 (houdunren.com)

1.作用域

1)函数被执行后其环境变量将从内存中删除。下面函数在每次执行后将删除函数内部的 total 变量。

 function count() {

        let total = 0;

}

count ();

2)函数每次调用都会创建一个新作用域

3)如果子函数被使用时父级环境将被保留(构造函数也是很好的环境例子)

function hd() {

let n = 1;

return function() {

let b = 1;

return function() {

        console.log(++n); console.log(++b);

};

};

}

let a = hd() () ;

a(); //2,2

a(); //3,3

4)let/const,使用let/const 可以将变量声明在块作用域中(放在新的环境中,而不是全局中)

5)在 for 循环中使用let/const 会在每一次迭代中重新生成不同的变量

let arr = [];

for (let i = o; i < 10; i++) {

arr.push((() => i)

};

console.log(arr[3]());//3 如果使用var声明将是10

6)在没有let/const 的历史中使用以下方式产生作用域

//1.自行构建闭包 var arr = [];

for (var i = o; i < 10; i++) {

(function (a){

arr.push(()=>a);

}) (i);

}

console.log(arr[3]()); //3

//2.闭包

闭包指:子函数可以访问外部作用域变量的函数特性,即使在子函数作用域外也可以访问。

·Js中的所有函数都是闭包

闭包一般在子函数本身作用域以外执行,即延伸作用域

1)闭包基本展示

function hd() {

let name ='后盾人;

return function () {

return name;

}

let hdcms = hd();

console.log(hdcms());//后盾人

2)使用闭包返回数组区间元素

let arr = [3, 2, 4,1, 5,6];

function between(a, b) {

return function(v) {

return v >= a && v <= b;

};

}

console.log(arr.filter(between(3,5)));

*3)闭包排序,使用闭包按指定字段排序

let lessons = [

{title:"媒体查询响应式布局", click:89, price:12},

{title:"FLEX 弹性盒模型" click:45, price: 120},

{title:"GRID 栅格系统", click:19, price:67},

{title:"盒子模型详解" click: 29, price: 300}

];

function order(field){

return (a, b) => (a[field] > b[field] ? 1 :-1);

}

console.table(lessons.sort(order("price")));

*4)闭包问题

(1)内存泄漏

闭包特性中,上级作用域会为函数保存数据,从而造成的如下所示的内存泄漏问题

<body>

<div desc="houdunren">在线学习</div><div desc="hdcms">开源产品</div>

</body>

<script>

let divs = document.querySelectorAll ("div");

divs.forEach(function(item) {

item.addEventListener("click",function() {

console.log(item.getAttribute("desc"));

});

item && console.log(item.getAttribute("desc"));// 回调函数外面,依然可以访问});

</script>

***下面通过清除不需要的数据解决内存泄漏问题

let divs = document.querySelectorAll ("div");

divs.forEach(function(item) {

let desc = item.getAttribute("desc");

item.addEventListener("click",function() {

console.log(desc);

})

item =null;

item && console.log(item.qetAttribute("desc"));// 回调函数外面,清除了不需要的数据,就不可访问了

});

(2)this 指向

this 总是指向调用该函数的对象,即函数在搜索 this 时只会搜索到当前活动对象。

下面是函数因为是在全局环境下调用的,所以 this 指向 window,这不是我们想要的。

let hd = {

user:"后盾人",

get:function(){

return function() {

return this.user;};

}

};

console.log(hd.get()());//undefined

***使用箭头函数解决这个问题

let hd = {

user:"后盾人",

get:function(){

return () => this.user;

}

};

console.log(hd.get()());//后盾人

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值