js 变量、函数提升
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 变量、函数提升相关推荐
- Js 变量声明提升和函数声明提升
Js代码分为两个阶段:编译阶段和执行阶段 Js代码的编译阶段会找到所有的声明,并用合适的作用域将它们关联起来,这是词法作用域的核心内容 包括变量声明(var a)和函数声明(function a(){ ...
- js高级第一章--变量提升,函数提升
js高级第一章–变量提升,函数提升 文章目录 前言 一.什么是js里的提升? 二.js变量提升 三.js函数提升 四.特殊情况 总结 前言 在js中,最基本的声明方式有三种,即:var,let,con ...
- js中函数声明先提升还是变量先提升
根据官方书籍<你不知道的javascript>(上卷)中写道: "函数会首先被提升,然后才是变量". 例子: console.log(foo); function fo ...
- 深入理解js的变量提升和函数提升
一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...
- JS函数简单的底层原理 -变量重复声明无效,隐式申明,变量提升,函数提升,以及堆栈内存的变化
JS函数简单的底层原理 (个人理解): 1. 已经使用var申明且赋值,若再次申明,则第二次申明(不赋值)无效. 2.在同一个作用域下,只要是发生了同名,且变量完成赋值,后者会覆盖前者.存在两个相同的 ...
- js中立即执行函数会预编译吗_js变量提升和函数提升
把变量提升函数提升拿出来讲,一看就知道是老前端搬砖工了,其实这些js的基础本质的东西,很有必要去了解,可以活跃思维,而且可以在研究这个的过程中,找到当初设计这门语言的人的想法,然后让自己不仅仅是对这个 ...
- js中变量名提升和函数名提升
首先,js中变量没有块级作用域,但是有函数作用域,即只有函数可以约数变量的作用域. 并且,函数的实质也是一个变量,所以可以改变它的值,即赋值.所以变量名提升和函数名提升非常相像. 1.变量名的提升发生 ...
- js函数提升和变量提升_关于在js中提升的真相
js函数提升和变量提升 Earlier this week I was preparing to give a tech talk about some foundational JavaScript ...
- js 变量、函数重复声明和变量提升浅析
第一阶段:看山是山,看水是水 先从简单的例子开始 // 示例1 var a = 1 console.log(a) // 1 var a = 2 console.log(a) // 2 通过两个var声 ...
最新文章
- android 定位 闪退_Android使用百度地图出现闪退及定位时显示蓝屏问题
- 学习笔记02:直播串讲02
- php 匹配双字节字符串,收集一些常用的正则表达式(匹配中文字符、匹配双字节字符、匹配HTML标记、匹配空行 and so on~~~)...
- [Swift实际操作]八、实用进阶-(7)使用通知的方法进行对象间的消息传递
- Mysql(一)——基础知识
- Spring MVC——数据检验步骤
- HTML+CSS(PC端+移动端)
- 等保三级全称是什么?是什么意思?
- 被夸大的伊朗“Twitter革命”
- RGB 转换为灰度图、二值化图
- Android全面屏导航栏高度,Android10全面屏开启底部手势横条,弹窗留白问题
- 顺序表的基本操作——初始化表
- QT5百度地图开发学习——qt调用JavaScript函数并传参
- 斗鱼主播查询易语言代码
- python关键字定义_python 关键字与含义
- 行星怎么画简单又漂亮,有手就会系列,超级简单!
- ajax使用频率,AJAX轮询频率 - 要长期轮询还是不轮询长轮询?
- 数据分析Pandas
- C语言课程设计——家庭财务管理系统源码
- C++求救,希望有现成代码
热门文章
- eclipse 右键项目为什么没有properties菜单_只需几步,从零开始搭建SSM项目
- python圣诞树代码成品图片动态_Python 圣诞树和樱花树源码
- android 默认打开服务器地址,Android开发实现任意切换服务器地址
- 今日工作总结及计划: 2022-02-14
- 12.5.2 升12.5.3的补丁 linux下载,游戏1.17/2.12/3.8/4.5/5.2更新内容[附离线补丁下载地址]...
- python怎么输出结果_如何在python中打印SQLite查询的结果?
- kudu接受kafka消息_Kafka入门详解
- Java实用教程笔记 Java多线程机制
- 顺序队列相关操作(C语言实现)
- MongoDB 安装配置