作用域:
作用域链:
子作用域能访问父级作用域的变量和方法。父集却不能访问子集作用域的变量和方法
变量声明提升:
js执行的时候会分为两个阶段:(JS的预编译 与 自上而下执行)
js预编译:js声明的时候会把var声明和函数提到script的最顶端(也可以理解为当前作用域),赋值语句不会被提升而是在原地等待赋值
赋值语句不提升:
console.log(a) var a=3; var a=function(){ console.log(1) } //undefined
函数体会被提升(且优先级高于变量声明):
var a=3; console.log(a) function a(){ console.log(1) }
如果在函数内部会提升到函数内部的最顶端:
var a=function(){ var b=3 function b(){ console.log('jj') } console.log(b) }()
变量的声明*(undefined)是不会覆盖任何东西的:
function test(){ console.log(2); } var test; console.log(test); var test = function(){ console.log(1); } console.log(test);
服从就近原则:
var a=4 var b=function(){ a=3 console.log(a) }() //3
当一个函数在另外一个函数内部被调用时它的作用域还是原来那个函数的作用域(如果想把当前作用域的变量传递进去需要传参):
function x() { console.log(a) } var y=function(){ var a=2 x() }() // a is not defined
大家肯定很奇怪这题,说好的同步执行自上而下呢
(function y(){ var a=2 x(a) })() function x(a){ console.log(a) } // 其实就相当于 function y(){ var a=2 x(a) } y() function x(a){ console.log(a) }
在严格模式下(use strict)
写变量的时候必须要声明不然会报错
"use strict" a=3 //a is not defined
"use strict" (function x(){ console.log(1) })() // 严格模式下不能使用自调用函数
"use strict" x=function(){ console.log(1) }() //1 x is not defined 写函数的时候声明会执行但是也会报错
在ES6中新增了2个声明(let const)
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
{let a=4} function x(){ console.log(a) } x() //a is not defined
const用来定义常量,使用时必须初始化(即必须赋值 不然报错),只能在块作用域里访问,而且不能修改。
const a console.log(a) //Missing initializer in const declaration
1.在ES6中不允许重新被定义
let a=4; var a=2 console.log(a) // Identifier 'a' has already been declared
var a=4 let a=3 console.log(a) // Identifier 'a' has already been declared
a=4; let a=3; console.log(a) //a is not defined
2.变量不允许声明提升
console.log(a) let a=3 //a is not defined
3.let定义变量的时候可以将值保留在块级作用域中
var oLi=document.querySelectorAll('#box li') for(let i=0;i<4;i++){ oLi[i].onclick=function(){ console.log(i) //0,1,2,3 } }