详解js变量声明提升
2016-11-07 15:02
316 查看
之前一直觉会认为javascript代码执行是由上到下一行行执行的。自从看了《你不知道的JS》后发现这个观点并不完全正确。先来给大家举一个书本上的的例子:
一开始我觉得输出的是undefined。但是真正的结果是helloworld。带着疑问再看另外一段代码:
借鉴与上面的例子会认为会输出一个helloworld,或者是抛出一个没有声明的异常错误,然而发现这两种想法也是错误。输出的结果是‘undefined’。这书非常人性化的总结出了结论是:
引擎解释javascript代码的之前会对其进行编译。在编译过程中会查找所有声明,并用合适作用域将他们关联起来。换句话说,在代码执行之前,会对作用域链中所有变量和函数声明先处理完先。所以,当遇到vara='helloworld'中是vara是先在编译阶段执行,然后在执行a='helloworld'。所以,第一段代码实质上是:
所以输出的就就是helloworld。总结一句话就是:只有声明被提升,而赋值或其他运算会留在原地。所以第二段代码实际上就是:
介绍完这两个经典例子是时候来看看一下这个例子了:
根据javascript的运行机制和javascript没有块作用域这个特点,可以得出,变量name会声明提升移至作用域scope(全局域或者当前函数作用域)顶部的。所以上述代码就相当于:
因此,if判断的时候typeofname=='undefined'是true。所以会执行条件为true里面的代码。输出就是Helloyang。
那么如果想实现上面的函数,我们该如何实现?答案非常简单那就创建块作用域了。如何最简单的创建块作用域呢?那当然是采用es6的新特性let关键字。let关键字可以将变量绑定到所在的任意区域中通常在{...}中。换句话说。let为其声明变量隐性劫持到所在区域中。下列例子中:let就绑定到
注意点:let所在的块级作用域,在声明代码被运行前,是不会像var那样会被查找到,提前声明,而是运行到了该代码才会被声明执行。下面例子很好说明这个问题:
vara='helloworld'; vara; console.log(a);
一开始我觉得输出的是undefined。但是真正的结果是helloworld。带着疑问再看另外一段代码:
console.log(a); vara='helloworld';
借鉴与上面的例子会认为会输出一个helloworld,或者是抛出一个没有声明的异常错误,然而发现这两种想法也是错误。输出的结果是‘undefined’。这书非常人性化的总结出了结论是:
引擎解释javascript代码的之前会对其进行编译。在编译过程中会查找所有声明,并用合适作用域将他们关联起来。换句话说,在代码执行之前,会对作用域链中所有变量和函数声明先处理完先。所以,当遇到vara='helloworld'中是vara是先在编译阶段执行,然后在执行a='helloworld'。所以,第一段代码实质上是:
vara;
a='helloworld';
console.log(a);
所以输出的就就是helloworld。总结一句话就是:只有声明被提升,而赋值或其他运算会留在原地。所以第二段代码实际上就是:
vara;
console.log(a);
a='helloworld';
介绍完这两个经典例子是时候来看看一下这个例子了:
varname="world";
(function(){
if(typeofname=='undefined'){
varname='yang';
console.log('Hello'+name)
}else{
console.log('Hello'+name)
}
})()
根据javascript的运行机制和javascript没有块作用域这个特点,可以得出,变量name会声明提升移至作用域scope(全局域或者当前函数作用域)顶部的。所以上述代码就相当于:
varname="world";
(function(){
varname;
if(typeofname=='undefined'){
varname='yang';
console.log('Hello'+name)
}else{
console.log('Hello'+name)
}
})()
因此,if判断的时候typeofname=='undefined'是true。所以会执行条件为true里面的代码。输出就是Helloyang。
那么如果想实现上面的函数,我们该如何实现?答案非常简单那就创建块作用域了。如何最简单的创建块作用域呢?那当然是采用es6的新特性let关键字。let关键字可以将变量绑定到所在的任意区域中通常在{...}中。换句话说。let为其声明变量隐性劫持到所在区域中。下列例子中:let就绑定到
if(typeofname=='undefined'){...}中。所以name不会被提升,所以判断就为假,于是就可以输出我们期待已久的‘helloworld’。
varname="world";
(function(){
if(typeofname=='undefined'){
letname='yang';
console.log('Hello'+name)
}else{
console.log('Hello'+name)
}
})()
注意点:let所在的块级作用域,在声明代码被运行前,是不会像var那样会被查找到,提前声明,而是运行到了该代码才会被声明执行。下面例子很好说明这个问题:
(function(){
console.log(b);
letb=2;
})()
相关文章推荐
- 详解js变量声明提升
- js 函数定义,使用,作用域,变量声明提升,遇解析.....
- 基于js的变量提升和函数提升(详解)
- JS 变量和函数的声明提升
- js变量声明提升&undefined
- Js中有关变量声明和函数声明提升的问题
- js 的变量声明提升,以及赋值不提升
- JavaScript中Hoisting详解 (变量提升与函数声明提升)
- Js 变量声明提升和函数声明提升
- js变量声明提升
- js变量声明提升
- JS变量声明提升、函数声明提升
- js变量声明提升,变量作用域与函数作用域,作用域链
- Js 变量声明提升和函数声明提升
- JS中变量声明及作用域详解
- js变量,声明提升的坑
- js代码执行过程,js预编译,变量声明提升,函数体整体提升
- 详解变量声明提升和函数声明提升
- 第24天:js-函数变量声明提升
- JS面试中的的变量提升和函数声明