var tt = 'aa'; function test(){ alert(tt); var tt = 'dd'; alert(tt); } test();
为什么第一个弹出undifine呢?
又:
var tt = 'aa'; function test(){ alert(tt); //var tt = 'dd'; //alert(tt); } test();
弹出aa?
求各位大神解答下
认证0级讲师
这题总结下来就2点知识: 1. 声明提升 2. 作用域链
先说后者,js在访问一个变量时会优先在该作用域(访问时的那个作用域)内寻找是否声明过该变量,如果该变量已经存在,则直接使用它的值,否则它会寻找该作用域的‘父作用域/上级作用域’,以此类推,直到找到全局作用域为止。
关于声明提升是指:js在解析的时候总是会将var, function这类关键词的声明语句提升至该作用域的最顶部(注意:这里只会提升声明部分)。
var
function
于是你那段代码等价于下面
javascriptvar tt = 'aa'; function test(){ var tt; //这个tt未被赋值,按js的‘规矩’,它的值是`undefined` alert(tt); tt = 'dd'; alert(tt); } test();
javascript
var tt = 'aa'; function test(){ var tt; //这个tt未被赋值,按js的‘规矩’,它的值是`undefined` alert(tt); tt = 'dd'; alert(tt); } test();
所以执行的时候返回的是 undefined 和 dd.
undefined
dd
广告 更多精彩内容你或许不知道的javascript,css细节
这样是全局的:
javascriptvar tt = 'aa'; function test() { alert(tt); } test();
var tt = 'aa'; function test() { alert(tt); } test();
这是你的例子:
javascriptvar tt = 'aa'; function test() { alert(tt); var tt = 'dd'; alert(tt); } test();
var tt = 'aa'; function test() { alert(tt); var tt = 'dd'; alert(tt); } test();
在函数内部使用var声明变量,是局部的。优先级高于函数外部的全局变量。 这个说明js解释器的解析顺序,尽管你的alert(tt)在var tt = 'dd'前面,但是它还是认为你是在内部定义了一个局部变量。
alert(tt)
var tt = 'dd'
javascriptfunction test() { var tt; alert(tt); tt = 'dd'; alert(tt); }
function test() { var tt; alert(tt); tt = 'dd'; alert(tt); }
这个是 js 的作用域和提升的问题,参考这篇文章 http://dyy.im/4406.html
这是JS的解释机制,第一个会理解成: function test(){ var tt; alert(tt); tt = 'dd'; alert(tt); }
这个时候函数内作用域的 tt 优先于外面的 tt
函数内的变量也会有类似函数声明提升的效果,test内的相当于 function test(){ var tt; //先定义,但未赋值。这里把全局(或者父函数)的tt给覆盖了 alert(tt); tt = 'dd'; //这里才给tt赋值。 alert(tt); }
我来将整个执行过程给你捋一捋哈
0.明白一个机制: 开始执行Js文件时,它会先扫描下整个js文件再去执行代码,会创建全局对象,搜索函数外面的 “var” 声明语句(此时并未赋值,为undefined), 在这面试题中,在全局对象中创建 tt 属性,tt = undefined,创建全局的执行环境,作用域链只有一个对象:全局对象 1.代码执行过程: var tt = 'aa';变量名解析开始,在全局对象属性中查找tt属性,把"aa"赋给tt。 跳过函数声明 test();遇到test()函数调用:创建调用对象 搜索函数中的var声明语句和参数,在调用对象中创建tt的属性,tt=undefined (这里很重要,tt现在是undefined) 创建函数执行环境,作用域链:调用对象>全局对象 回到函数,依次执行代码: alert(tt),查询tt,变量名解析,先搜索调用对象,找到tt属性,其值为undefined,执行弹出undefined,(这就是为什么了) var tt="dd",查询tt,变量名解析,先搜索调用对象,找到tt属性,tt="dd" alert(tt),查询tt,变量名解析,先搜索调用对象,找到tt属性,其值为"dd",执行弹出dd
这个问题涉及到函数的执行环境和作用域链,建议你去了解下哦。第二个函数你应该懂了不用解释了吧。
求采纳啊
详解见javascript变量声明提升(hoisting) - SegmentFault
知道代码是分两个阶段执行就行了 解析和进入上下文[变量 函数等声明]阶段 第二个阶段是代码执行
js的作用域不是块作用域而是函数作用域 这个是js变量的声明提前
主要考点就是变量申明提前 到作用域内的顶部
这题总结下来就2点知识:
1. 声明提升
2. 作用域链
先说后者,js在访问一个变量时会优先在该作用域(访问时的那个作用域)内寻找是否声明过该变量,如果该变量已经存在,则直接使用它的值,否则它会寻找该作用域的‘父作用域/上级作用域’,以此类推,直到找到全局作用域为止。
关于声明提升是指:js在解析的时候总是会将
var
,function
这类关键词的声明语句提升至该作用域的最顶部(注意:这里只会提升声明部分)。于是你那段代码等价于下面
所以执行的时候返回的是
undefined
和dd
.广告
更多精彩内容你或许不知道的javascript,css细节
这样是全局的:
这是你的例子:
在函数内部使用var声明变量,是局部的。优先级高于函数外部的全局变量。
这个说明js解释器的解析顺序,尽管你的
alert(tt)
在var tt = 'dd'
前面,但是它还是认为你是在内部定义了一个局部变量。这个是 js 的作用域和提升的问题,参考这篇文章 http://dyy.im/4406.html
这是JS的解释机制,第一个会理解成:
function test(){
var tt;
alert(tt);
tt = 'dd';
alert(tt);
}
这个时候函数内作用域的 tt 优先于外面的 tt
函数内的变量也会有类似函数声明提升的效果,test内的相当于
function test(){
var tt; //先定义,但未赋值。这里把全局(或者父函数)的tt给覆盖了
alert(tt);
tt = 'dd'; //这里才给tt赋值。
alert(tt);
}
我来将整个执行过程给你捋一捋哈
0.明白一个机制: 开始执行Js文件时,它会先扫描下整个js文件再去执行代码,会创建全局对象,搜索函数外面的 “var” 声明语句(此时并未赋值,为undefined),
在这面试题中,在全局对象中创建 tt 属性,tt = undefined,创建全局的执行环境,作用域链只有一个对象:全局对象
1.代码执行过程: var tt = 'aa';变量名解析开始,在全局对象属性中查找tt属性,把"aa"赋给tt。
跳过函数声明
test();遇到test()函数调用:创建调用对象
搜索函数中的var声明语句和参数,在调用对象中创建tt的属性,tt=undefined (这里很重要,tt现在是undefined)
创建函数执行环境,作用域链:调用对象>全局对象
回到函数,依次执行代码:
alert(tt),查询tt,变量名解析,先搜索调用对象,找到tt属性,其值为undefined,执行弹出undefined,(这就是为什么了)
var tt="dd",查询tt,变量名解析,先搜索调用对象,找到tt属性,tt="dd"
alert(tt),查询tt,变量名解析,先搜索调用对象,找到tt属性,其值为"dd",执行弹出dd
这个问题涉及到函数的执行环境和作用域链,建议你去了解下哦。第二个函数你应该懂了不用解释了吧。
求采纳啊
详解见javascript变量声明提升(hoisting) - SegmentFault
知道代码是分两个阶段执行就行了
解析和进入上下文[变量 函数等声明]阶段
第二个阶段是代码执行
js的作用域不是块作用域而是函数作用域
这个是js变量的声明提前
主要考点就是变量申明提前 到作用域内的顶部