美文网首页
js变量提升 函数提升 作用域

js变量提升 函数提升 作用域

作者: 白小纯kl | 来源:发表于2020-02-04 15:47 被阅读0次

js代码解析原则

js引擎首先在读取js代码时默认执行2个步骤:
1.解释(通篇扫描所有js代码,然后把所有声明(变量申明、函数声明)提升到对应作用域顶端)
2.执行(执行逻辑操作)

变量提升

例1.
console.log(b)
b=2; //输出 ReferenceError: b is not defined
例2.
console.log(b)
var b=2; //输出 undefined
----------
可以直观的发现例1、例2区别就是因为一个没有用var申明变量,导致不同的输出。
js引擎在解释的时候,例2相当于:
 var b;
 console.log(b);//由于未赋值 输出undefined 
 b=2; 
而针对例1而言,不会改变代码顺序,遇到b时,b还没被申明,只能输出b is not defined。

函数提升

首先要知道函数定义有两种方式的,一种是函数定义表达式,一种是函数声明语句。
//函数定义表达式 
var f = function (){ 
... 
}; 
//函数声明语句 
function f(){ 
 ... 
}
重点:函数提升针对是函数声明语句而言,其次变量提升只提升变量名而函数提升会提升整个函数体。
----------
例1.
f();
function f(){
  console.log("fffff");
} 
//输出 fffff
例2.
f();
var f=function(){
  console.log("fffff");
} 
//输出 TypeError f is not a function
----------
为什么例1正确执行呢,其原因就是函数提升,在js引擎解释的时,相当于:
function f(){
  console.log("fffff");
} 
f();//正确执行函数,输出fffff
而例2则相当于:
var f;
console.log(f); //undefined
f();//f不是一个函数 f is not a function
f=function(){
  console.log("fffff");
}  
----------
再来看看例3
console.log(f);
var f=10;
console.log(f);
function f(){
   console.log('fff');
 }
console.log(f);
输出:
ƒ f(){
   console.log('fff');
 }
10
10
这个例子就考察了一个优先级问题,函数提升会在变量提升的上面,在js引擎解释的时候就相当于:
function f(){
   console.log('fff');
 }
 var f;
 console.log(f);
 //ƒ f(){
   console.log('fff');
f=10
console.log(f);// 10
console.log(f);// 10

作用域

es5中只有全局作用域和函数作用域,es6新增了块级作用域。
var v = "hello";
if(true){
  console.log(v);
  var v = "world";
}
//输出 hello 说明es5是没有块级作用域
es6对块级作用域的支持
let n = 5;
if (true) {
    let n = 10;
 }
console.log(n); // 5
----------
es5中:
var v = "hello";
(function(){
  console.log(v);
  var v= "world";
})()
//输出 undefined 
原因函数作用域变量v遮盖了上层作用域变量v,再加上变量提升,相当于:
var v = "hello";
(function(){
  var v;
  console.log(v);// undefined
  v = "world";
})()
----------
es6允许块级作用域的任意嵌套。外层作用域无法读取内层作用域的变量。内层作用域可以定义外层作用域的同名变量。
{{
  {let insane = 'Hello World'}
  console.log(insane); //ReferenceError: insane is not defined
}};
{{
 let insane = 'Hello World';
  {let insane = 'Hello World';}
}};
----------
es6也规定,函数本身的作用域,在其所在的块级作用域之内。
function f() { console.log('I am outside!'); }
(function () {
  if(false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }
  f();   
}())
上面代码在es5中运行,输出 I am inside!,但是在es6中运行,会输出I am outside!。
这是因为es5存在函数提升,不管会不会进入 if代码块,函数声明都会提升到当前作用域的顶部,得到执行;
而es6支持块级作用域,不管会不会进入if代码块作用域,其内部声明的函数皆不会影响到作用域的外部。
----------
块级作用域外部,无法调用块级作用域内部定义的函数。
if(1==2){
  let a = 'secret';
  function f() {
    return a;
  }
}
f()//TypeError: f is not a function
----------
块级作用域内let和const命令所声明的变量,只在命令所在的代码块内有效。
if(true){
  let a = 10;
  var b = 1;
}
console.log(a)//ReferenceError: a is not defined.
console.log(b)// 1

相关文章

  • js 的变量提升和函数提升

    1. 深入理解 js 的变量提升和函数提升 先了解:js没有块级作用域,只有全局作用域,和函数作用域 相同的函数名...

  • let const var

    变量提升 函数会优先于变量提升; 函数提升会把整个函数移到作用域顶部 变量提升智慧把变量的定义移到作用域顶部 wi...

  • JS 提升

    变量提升即将变量声明提升到它所在作用域的最开始的部分 在 js 中只有两种作用域,全局作用域和函数作用域,在ES6...

  • 作用域与变量提升

    作用域与变量提升 作用域 JS中变量的作用域有全局作用域和局部作用域两种,作用域简单来讲就是变量与函数的可访问范围...

  • js变量提升

    JS把定义在后面的变量(并不赋值)或函数(整个函数)提升到前面定义。作用域(scoping)变量提升(Hoisti...

  • 2019-11-11-本周学习周报

    学习总览 JavaScript 函数作用域、块级作用域 变量提升、函数提升 CSS 新增属性transition ...

  • es6

    let const var 函数提升优先于变量提升,函数提升会把整个函数挪到作用域顶部,变量提升只会把声明挪到作用...

  • 全面理解作用域

    es5:函数作用域、全局作用域 (var 、function有变量提升)es6:块级作用域 (没有变量提升...

  • JavaScript 函数声明与函数表达式的区别

    函数声明 存在函数提升(同比于变量提升) 函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪...

  • js作用域、变量提升、函数提升

    先看一个题目 alert的结果是 10 再看下一个: alert结果是1 如果以上题目都答对了,那可能接下来的内容...

网友评论

      本文标题:js变量提升 函数提升 作用域

      本文链接:https://www.haomeiwen.com/subject/nuwrxhtx.html