全局作用域
全局环境会被依赖不会被回收
函数作用域
函数调用多次会产生多个内存地址,调用一次存一份数据,他们之间不会共享
function hd() {
let n = 1;
function sum() {
console.log(++n)
}
sum()
}
// 不管执行多少次n都是2,函数被调用会产生新的内存地址
hd();
hd();
hd();
函数定义的数据作用域范围是函数本身及其子函数,不会向父级进行传递
function hd() {
let n = 1;
return function sum() {
console.log(++n)
}
sum(); // return后面的不执行
}
// hd 函数里的sum 让外边用(return 出去), n就会一直存在
let a = hd()
a(); // 2
a(); // 3
a(); // 4
let b = hd(); // 调用一次函数会产生新的内存地址
b(); // 2
b(); // 3
let c = hd();
c(); // 2
构造函数
function Hd() {
let n = 1;
this.sum = () => {
console.log(++n)
}
}
let a = new Hd() // 创建实例对象a里边有个sum属性,值是函数,在被使用,同作用域下的n会被保留
a.sum(); // 2
a.sum(); // 3
a.sum(); // 4
// 相当于
function Hd() {
let n = 1;
function sum() {
console.log(++n)
}
return {
sum
}
}
let a = new Hd() // { sum: function}
a.sum(); // 2
a.sum(); // 3
a.sum(); // 4
块级作用域
{
let a = 1;
console.log(a); // 1
let a = 2; // 同级作用域下不能重复声明变量
console.log(a);
}
{
let a = 2;
console.log(2); // 两个块级作用域内存地址不一样,可以重复声明变量
}
console.log(a); // 不可以使用
for 循环是有块级作用域的
for (var i = 1; i <= 3; i++) {
console.log(i); // 1, 2, 3
}
console.log(i); // var 声明的变量在全局作用域下, i是4
for (let i = 1; i <= 3; i++) {
console.log(i); // 1, 2, 3
}
console.log(i); // 不可以使用
for (var i = 1; i <= 3; i++) {
setTimeout(() => {
console.log(i); // setTimeout 为宏任务,后执行 打印 3次4
}, 1000)
}
console.log(i, 'i'); // 先执行 4
for (let i = 1; i <= 3; i++) {
setTimeout(() => {
console.log(i); // 1, 2, 3
}, 1000)
}
使用var 模拟伪块级作用域
for (var i = 1; i <= 3; i++) {
(function (a) { // 使用函数作用域
setTimeout(() => {
console.log(a)
}, 1000)
})(i)
}
闭包
闭包是指一个函数可以访问到其他函数作用域当中的变量
存在问题:内存泄漏
<body>
<button>张东旭</button>
<script>
let btns = document.querySelectorAll('button')
btns.forEach(item => {
let flag = false
item.addEventListener('click', () => {
if (!flag) {
flag = setInterval(() => {
let n = 0;
item.style.left = `${ ++n }px`
}, 5)
}
})
})
</script>
</body>
<body>
<div desc="zdx">zdx</div>
<div desc="let it be">let it be</div>
<script>
const divs = document.querySelectorAll('div')
divs.forEach(item => {
let desc = item.getAttribute('desc') // 2优化内存
item.addEventListener('click', () => {
// console.log(item.getAttribute('desc'))
// console.log(item)
console.log(desc) // 2优化内存
})
item = null // 2优化内存
})
</script>
</body>