猎聘网网站谁做的,国内团购网站做的最好的是,网站开发的工作经验,wordpress外网跳转JS作用域#xff1a;全局作用域#xff0c;函数作用域#xff0c;块级作用域 背景作用域全局作用域函数作用域块级作用域通过调用栈分析块级作用域开发者工具查看作用域选项卡示例 背景
由于 JavaScript 存在变量提升这种特性#xff0c;从而导致很多与直觉不符的代码全局作用域函数作用域块级作用域 背景作用域全局作用域函数作用域块级作用域通过调用栈分析块级作用域开发者工具查看作用域选项卡示例 背景
由于 JavaScript 存在变量提升这种特性从而导致很多与直觉不符的代码这也是 JavaScript 的一个重要设计缺陷这种设计缺陷带来的问题可以去看看JS变量和函数提升。
所以 ES6 通过引入块级作用域并配合 let、const 关键字来避开了这种设计缺陷但是由于 JavaScript 需要向下兼容所以变量提升在相当长一段时间内还会继续存在。
作用域
作用域是指在程序中定义变量的区域该位置决定了变量的生命周期。即作用域是变量和函数的可访问范围控制着变量和函数的可见性和生命周期。
ES62015年6月 之前ES 的作用域只有两种全局作用域和函数作用域。相较而言其他语言则都普遍支持块级作用域。
全局作用域
全局作用域中的对象在代码中的任何地方都能访问其生命周期伴随着页面的生命周期。
函数作用域
函数作用域就是在函数内部定义的变量或函数并且定义的变量或函数只能在函数内部被访问函数执行结束后函数内部定义的变量就会被销毁。
块级作用域
ES6 中给 JavaScript 新增了块级作用域
块级作用域由{}包括if语句和for语句里面的{}都属于块级作用域var定义的变量没有块级作用域概念可以跨块级作用域访问let和const定义的变量只能在块级作用域里访问
下面几段示例代码可以帮助你对块级作用域的理解
{var a 1let b 2const c 3
}
console.log(a) // 1
console.log(b) // 报错let和const只能在块级作用域中访问
console.log(c) // 报错for(var a 0; a 3; a) {var d 5
}
console.log(a) // 3
console.log(d) // 5for(let a 0; a 3; a) {var d 5
}
console.log(a) // 报错for语句属于块级作用域
console.log(d) // 5if(true) {var a 5
}
console.log(a) // 5if(true) {let a 5
}
console.log(a) // 报错if语句属于块级作用域通过调用栈分析块级作用域 不了解调用栈的可以先去看JS调用栈 function foo() {var a 1let b 2{let b 3var c 4let d 5console.log(a)console.log(b)}console.log(b)console.log(c)console.log(d)
}
foo()第一步编译并创建执行上下文。函数内部通过 var 声明的变量在编译阶段全都被存到变量环境里 第二步继续执行代码。执行到函数内部代码块在块级作用域之前变量环境中的 a 已经被设置成了 1词法环境中的 b 已经被设置成了 2。 进入函数内的块级作用域块级作用域中通过 let 声明的变量会被存放在词法环境一个单独的区域中这个区域中的变量并不影响块级作用域块外面的变量比如它们都有一个变量 b。其实在词法环境中维护了一个小型的栈结构栈底时函数最外层的变量进入一个块级作用域后就会把该作用域内的变量压入栈中当该作用域执行完成后就从栈中弹出。当然这里的变量是指通过 let 或 const 声明的变量。 当执行到块级作用域中的 console.log(a) 这行代码时需要在词法环境和变量环境中查找 a 的值具体查找方向是沿着词法环境的栈顶向下查询如果有直接返回给 JavaScript 引擎如果都没有就去变量环境中查找。 块级作用域执行完后返回内容弹出栈中执行结果为
所以块级作用域是通过词法环境的栈结构来实现的而变量提升是通过变量环境来实现的通过两者的结合JavaScript 引擎也就同时支持了变量提升和块级作用域了。
开发者工具查看作用域
var a hello
let b 18
const c female
{var aa hilet bb 188const cc maledebugger
}
function foo() {var aaa golet bbb 10const ccc man{var aaaa oklet bbbb 8const dddd girldebugger}debugger
}
foo()打开Chrome开发者工具查看这段代断点处作用域下变量值 选项卡示例
stylebutton.active{color: red;}p{display: none;}p.active{display: block;background-color: red;}
/stylebodybutton选项一/buttonbutton选项二/buttonbutton选项三/buttonp内容一/pp内容二/pp内容三/p
/body// 用var
scriptlet buttons document.querySelectorAll(button)let ps document.querySelectorAll(p)for(var i 0; i buttons.length; i) {buttons[i].index ibuttons[i].onclick function() {for(var j 0; j buttons.length; j) {buttons[j].className ps[j].className }this.className activeps[this.index].className active}}
/script
/body// 使用let块级作用域
let buttons document.querySelectorAll(button)
let ps document.querySelectorAll(p)for(let i 0; i buttons.length; i) {buttons[i].onclick function() {for(var j 0; j buttons.length; j) {buttons[j].className ps[j].className }this.className activeps[i].className active // i的for循环每一次都会生成一个块级作用域所以每个i都在指定的作用域中工作}
}总结选项卡实例中使用var没有块级作用域所以for循环结束i就变成了最后的值所以必须要将索引值赋值给每一个元素然后点击的时候根据索引去判断显影性。 使用let创造了块级作用域每次循环都会创造一个块级作用域的i所以可以直接使用ps[i]去对对应的元素设置类名。