js 变量、函数提升

先简单理解下作用域的概念,方便对变量与函数提升的概念的理解

function foo() {var x = 1;if (x) {var x = 2;}console.log(x);
}
foo();// 2

结果为2,可见js中并没有块级作用域的概念
能够使用以下的方法创造自己的作用域。这样不会干扰到外部变量

function foo() {var x = 1;if (x) {(function() {var x = 2;}());}console.log(x);
}
foo();// 1

结果为1,可见js中的作用域是以函数为边界的

1.变量提升:

变量提升与js的预编译有关,以下通过样例辅助说明

var a = 100;
var b = 200;
function foo(){console.log(a);// undefineda = 10;console.log(a);// 10var a = 1;console.log(a);// 1console.log(b);// 200
}
foo();

js预编译时会先在当前作用域中找到var声明的变量分配空间。赋值为undefined。假设找不到就会到下一级作用域中找

上面的代码的等价代码例如以下:

var a = 100;
var b = 200;
function foo(){var a;console.log(a);// undefineda = 10;console.log(a);// 10a = 1;console.log(a);// 1console.log(b);// 200
}
foo();

这样看是不是easy理解多了。第一行var声明了a,可是没有赋值,因此为undefined。以下打印10、1也就顺理成章了。

至于变量b。它在当前作用域中找不到,因此须要到外层作用域中找。在window下找到了变量b,能够看到它的值为200

2.函数提升

首先要明白两点:

<1> 仅仅有函数声明才会进行函数提升

<2> 函数提升会将函数体一起提升上去,这点与变量提升有所不同

以下来证明函数表达式不能进行函数提升:

~function() {alert(typeof next); // undefined~function next() {alert(typeof next); // function}()
}()

函数前面加个~的目的是将函数声明变成函数表达式,实际上也能够加其他运算符。比方+,-,!等,总之这个函数声明被变成了函数表达式。

从打印结果来看第一个alert出的是undefined,说明next根本没有发生函数提升。

以下来接着验证:

a();// 123var a = function(){console.log("321");
}a();// 321function a(){console.log("123");
}

从结果能够看出,先打印出来的反而是放在后面的a()。上面代码的等价表演示样例如以下:

var a = function a(){console.log("123");
}a();a = function(){console.log("321");
}a();

那么假设当变量提升与函数提升同一时候发生的时候,哪个的优先级更高呢?我们来做个实验:

function fn(){console.log(a);var a = 2;function a(){}console.log(a);
}
fn();// function a(), 2

从打印顺序中能够看出。函数提升比变量提升优先级高。由于函数提升是将函数体总体提升,提升上去后立刻赋值。

等价代码例如以下:

function fn(){var a = function(){}console.log(a);a = 2;console.log(a);
}
fn();

以下再来几个有趣的样例:

B = 100;
function B(){B = 2;console.log(B);
}
B(); // B is not a function
//函数提升导致的B = 100;
var B = function(){B = 2;console.log(B);
}
B(); // 2
//函数表达式不存在函数提升
function change() {alert(typeof fn); // functionalert(typeof foo); // undefinedfunction fn() {alert('fn');}var foo = function(){<span style="white-space:pre">    </span>alert('foo');}var fn;
}
change();
//fn提升了,foo没有提升

以下还有几个思考题:

1.

var a = 1;
function b() {console.log(a);a = 10;  function a() {}
}
b();// ?
console.log(a);// ?

2.

a = 10;
(function a(){a = 1;console.log(a);// ?
})();

3.

function a(i) { console.log(i);// ?var i = 1; console.log(i);// ?
};
a(10); 

js 变量、函数提升相关推荐

  1. Js 变量声明提升和函数声明提升

    Js代码分为两个阶段:编译阶段和执行阶段 Js代码的编译阶段会找到所有的声明,并用合适的作用域将它们关联起来,这是词法作用域的核心内容 包括变量声明(var a)和函数声明(function a(){ ...

  2. js高级第一章--变量提升,函数提升

    js高级第一章–变量提升,函数提升 文章目录 前言 一.什么是js里的提升? 二.js变量提升 三.js函数提升 四.特殊情况 总结 前言 在js中,最基本的声明方式有三种,即:var,let,con ...

  3. js中函数声明先提升还是变量先提升

    根据官方书籍<你不知道的javascript>(上卷)中写道: "函数会首先被提升,然后才是变量". 例子: console.log(foo); function fo ...

  4. 深入理解js的变量提升和函数提升

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

  5. JS函数简单的底层原理 -变量重复声明无效,隐式申明,变量提升,函数提升,以及堆栈内存的变化

    JS函数简单的底层原理 (个人理解): 1. 已经使用var申明且赋值,若再次申明,则第二次申明(不赋值)无效. 2.在同一个作用域下,只要是发生了同名,且变量完成赋值,后者会覆盖前者.存在两个相同的 ...

  6. js中立即执行函数会预编译吗_js变量提升和函数提升

    把变量提升函数提升拿出来讲,一看就知道是老前端搬砖工了,其实这些js的基础本质的东西,很有必要去了解,可以活跃思维,而且可以在研究这个的过程中,找到当初设计这门语言的人的想法,然后让自己不仅仅是对这个 ...

  7. js中变量名提升和函数名提升

    首先,js中变量没有块级作用域,但是有函数作用域,即只有函数可以约数变量的作用域. 并且,函数的实质也是一个变量,所以可以改变它的值,即赋值.所以变量名提升和函数名提升非常相像. 1.变量名的提升发生 ...

  8. js函数提升和变量提升_关于在js中提升的真相

    js函数提升和变量提升 Earlier this week I was preparing to give a tech talk about some foundational JavaScript ...

  9. js 变量、函数重复声明和变量提升浅析

    第一阶段:看山是山,看水是水 先从简单的例子开始 // 示例1 var a = 1 console.log(a) // 1 var a = 2 console.log(a) // 2 通过两个var声 ...

最新文章

  1. android 定位 闪退_Android使用百度地图出现闪退及定位时显示蓝屏问题
  2. 学习笔记02:直播串讲02
  3. php 匹配双字节字符串,收集一些常用的正则表达式(匹配中文字符、匹配双字节字符、匹配HTML标记、匹配空行 and so on~~~)...
  4. [Swift实际操作]八、实用进阶-(7)使用通知的方法进行对象间的消息传递
  5. Mysql(一)——基础知识
  6. Spring MVC——数据检验步骤
  7. HTML+CSS(PC端+移动端)
  8. 等保三级全称是什么?是什么意思?
  9. 被夸大的伊朗“Twitter革命”
  10. RGB 转换为灰度图、二值化图
  11. Android全面屏导航栏高度,Android10全面屏开启底部手势横条,弹窗留白问题
  12. 顺序表的基本操作——初始化表
  13. QT5百度地图开发学习——qt调用JavaScript函数并传参
  14. 斗鱼主播查询易语言代码
  15. python关键字定义_python 关键字与含义
  16. 行星怎么画简单又漂亮,有手就会系列,超级简单!
  17. ajax使用频率,AJAX轮询频率 - 要长期轮询还是不轮询长轮询?
  18. 数据分析Pandas
  19. C语言课程设计——家庭财务管理系统源码
  20. C++求救,希望有现成代码

热门文章

  1. eclipse 右键项目为什么没有properties菜单_只需几步,从零开始搭建SSM项目
  2. python圣诞树代码成品图片动态_Python 圣诞树和樱花树源码
  3. android 默认打开服务器地址,Android开发实现任意切换服务器地址
  4. 今日工作总结及计划: 2022-02-14
  5. 12.5.2 升12.5.3的补丁 linux下载,游戏1.17/2.12/3.8/4.5/5.2更新内容[附离线补丁下载地址]...
  6. python怎么输出结果_如何在python中打印SQLite查询的结果?
  7. kudu接受kafka消息_Kafka入门详解
  8. Java实用教程笔记 Java多线程机制
  9. 顺序队列相关操作(C语言实现)
  10. MongoDB 安装配置