console.log(a)//undefined var a = 12; function b(arr){//变量提升阶段function就完成了声明和赋值,浏览器会在全局作用域声明一个b,然后再形成一个堆内存里面 //是函数体里面的代码字符串。这个堆内存会有一个16进制的地址,而全局里面声明的那个b就会指向这个地址 //因为函数在变量提升阶段就完成了声明和赋值,所以在代码执行阶段在遇到b这个函数就不会在重复声明赋值,就会直接跳过 for(let i=0;i<arr.length;i++){ console.log(i) } } //跳过后就会执行下面这个函数调用,传了一个数组进去。 //而执行一个函数也就是形成了一个私有栈内存。当私有的作用域形成后也不是立即代码执行,而是先进行变量提升(变量提升前,先形参赋值) b([1,2,3,4]) //在ES3和ES5语法规范中,只有全局作用域和函数执行的私有作用域(栈内存),其他大括号不会形成栈内存
console.log(i)//undefined console.log(window.i)//undefined console.log(‘i‘ in window)//true 在变量提升阶段,在全局作用域中声明了一个变量i,此时就已经把i当做属性值赋值 //给了window了,只不过此时还没有给i赋值,默认是undefined // in? :检测某个属性是否隶属于这个对象 var i = 9//变量值修改window的值也跟着修改 console.log(i)//9 console.log(window.i)//9 window的一个属性名为i i=13 console.log(window.i)//13 window.i=14 console.log(i)//14 重点:全局变量和window的属性存在‘映射机制’,就是有一个改变另一个也跟着改变
//console.log(j)//j is not defined 这里的J是按照变量的来识别的 //console.log(window.j)//undefined 这里是按照window的属性来识别的,因为对象没有某一个属性返回的就是undefined //console.log(window.j)//false 不存在这个属性 j=10// 这里不带var 就相当于给window加了一个属性叫j,值是10 console.log(j)//10 console.log(window.a)//12 // var q =10, // s =11 //这样写s是带var // var q = s =11 // 这样写不带var //在私有作用域中带var和不带var也有区别:带var在私有作用域变量提升阶段都声明为私有变量和外界没有任何关系 //不带var 不是私有变量,它会想它的上级作用域查找,看它是否是上级的变量,不是继续向上查找,一直找到window为止 //这种查找机制叫‘作用域链’ //console.log(n,m)//undefined undefined var n =13; m =13; function fn(){ console.log(n,m)//变量提升阶段先var了一个n所以是 undefined 但是m不带var,向上级查找所以m是13 ; var n = m = 14//此时都是14 console.log(n,m)//14 14 } fn() console.log(a,m)// 这里的a是全局的所以是13,b在函数里被重新赋值所以是14
function f(){ b = 13 console.log(‘b‘ in window)//true 在作用域查找的过程中,如果找到window也没有这个变量,相当于给window设置了 //了一个属性b console.log(b)//13 } f() console.log(b)//13
fnn()// fnn is not a function sun()//2 var fnn = function (){//函数表达式声明 因为是用var关键字声明在变量提升阶段只提升了等号左边的fnn, //但是并没有定义或赋值,所以在上面调用时报错 console.log(1) } fnn() function sun (){//普通方式声明的函数在 变量提升阶段就已经声明和定义完毕 所以上面可以直接执行 console.log(2) } sun()
console.log(z) if(1===2){//在当前作用域下,不管条件是否成功都要进行变量提升, //带var的还是只是声明 //带function的在老版本浏览器渲染机制下,声明+定义都处理,但是为了迎合es6中的块级作用域,新版浏览器对于函数 //(在条件判断中的函数),不管条件是否成立,都是先声明,没有赋值。 var z = 10 } console.log(z) if(1===1){ console.log(fs)//函数本身:当条件成立,进入到判断体中(ES6中它是以个块级作用域)第一件事并不是变量提升, //先把fs声明并定义,也就是判断体中代买执行前,fs就已经赋值了 function fs(){ console.log(‘ok‘) } } console.log(fs)//函数本身
console.log(a)//a is not defined let a =12 console.log(window.a)//undefined console/log(a)//12
原文:https://www.cnblogs.com/menggege/p/14184504.html