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);// undefined
a = 10;
console.log(a);// 10
var a = 1;
console.log(a);// 1
console.log(b);// 200
}
foo();
js预编译时会先在当前作用域中找到var声明的变量分配空间。赋值为undefined。假设找不到就会到下一级作用域中找
上面的代码的等价代码例如以下:
var a = 100;
var b = 200;
function foo(){
var a;
console.log(a);// undefined
a = 10;
console.log(a);// 10
a = 1;
console.log(a);// 1
console.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();// 123
var a = function(){
console.log("321");
}
a();// 321
function 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); // function
alert(typeof foo); // undefined
function 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中函数提升及var变量提示
其中,在javascript中,函数声明及var声明的变量会得到提升.但是函数声明会先于var声明的变量被提升.即便function写在后面. 看下面的例子: var aa = 221; functi ...
- 【JS】函数提升变量提升以及函数声明和函数表达式的区别
今天看js的变量提升问题,里面提到了函数提升.然后发现自己之前一直把函数声明和函数表达式弄错,导致函数提升出错 一.变量提升 console.log(a) var a=100 //undefined ...
- js变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级
原文出自:http://www.cnblogs.com/xxcanghai/p/5189353.html作者:小小沧海 题目如下: function Foo() { getName = functio ...
- JS变量的提升详解
此次说明的是var与function的变量提升 那么先看一段代码 <script type="text/javascript"> console.log(test); ...
- 解读JavaScript中的Hoisting机制(js变量声明提升机制)
hoisting机制:javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 知识点一:javascript是没有 ...
- 【JavaScript高级进阶】JavaScript变量/函数提升的细节总结
// 测试1 console.log('----------test1--------------'); console.log(global); // undefined var global = ...
- js变量声明提升
1.变量提升 根据javascript的运行机制和javascript没有块级作用域这个特点,可以得出,变量会声明提升移至作用域 scope (全局域或者当前函数作用域) 顶部的. 变量声明提升至全局 ...
- JS变量声明提升和函数声明提升
JS代码在执行的时候会先找出执行代码中定义的变量和函数,对其进行声明. 例1:console.log(a); var a = 4; 此时输出undefined.a变量在执行console.log(a) ...
- 详解js变量声明提升
之前一直觉会认为javascript代码执行是由上到下一行行执行的.自从看了<你不知道的JS>后发现这个观点并不完全正确.先来给大家举一个书本上的的例子: var a='hello wor ...
随机推荐
- 如何移除浏览器一启动就打开lunchpage.org
lunchpage.org 就是一个劫持网站.症状就是你打开你电脑上的任何浏览器都会重定向到一个广告页面.这个很烦! 解决方法: 1. 安装 Zemana AntiMalware 便携版. 2. 打开 ...
- django踩坑
django输入localhost或者127.0.0.1可以进入,输入自己ip报错 结局方案: 首先找到自己的项目的setting.py文件 找到——> ALLOWED_HOSTS = [] 修 ...
- tomcat域名配置
修改tomcat目录下的web配置文件 vim conf/server.xml 在host标签内添加 <Context path="bbs" docBase="/a ...
- 实现验证的vsftpd虚拟用户
实现基于文件验证的vsftpd虚拟用户--(一台) 一.创建用户数据库文件 vim /etc/vsftpd/vuser cd /etc/vsftpd/ db_load -T -t hash -f vu ...
- 5.12-leepcode 作业详解
leepcode 作业详解 1.给定一个整数数组,判断是否存在重复元素.如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 正确解答 class So ...
- JSTL标签判断list是否为空
jsp页面判断获得action传的list的是否为空或者list.size的长度,就可以用fn这个标签: <c:if test="${list== null || fn:length( ...
- 大数据学习——linux常用命令(四)
四 查到命令 1 查找可执行的命令所在的路径 which ls 查ls命令所在的路径 2 查找可执行的命令和帮助的位置 whereiis ls 3 从某个文件夹开始查找文件 find / -name ...
- android AlertDialog常见使用
android AlertDialog常见使用 简单提示框: AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); aler ...
- 2016 Multi-University Training Contest 1 solutions BY HIT
首先向大家表示抱歉,因为这套题是去年出的,中间间隔时间太长,今年又临时准备仓促, 所以部分题目出现了一些问题,非常抱歉. Abandoned country 首先注意到任意两条边的边权是不一样的,由此 ...
- [CodePlus2017]晨跑
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 166 Solved: 125 Description "无体育,不清华".&qu ...