js 变量、函数提升
2024-09-04 00:15:53
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);
最新文章
- css3新特性
- 【读书笔记】iOS网络-使用推送通知
- CGCDSSQ
- 最实用的IT类网站及工具大集合[转]
- git常用命令1
- Eclipse Maven to create Struts2 Project
- 使用git了解代码编写过程
- hdu 4696 Answers
- UIWebview 禁止某个方向滚动
- JS正则表达式收集篇
- AspectJ的安装和Eclipse的AJDT插件的配置
- 2016-09-06 J2EE基础知识之不知
- ASP.NET MVC4简单使用ELMAH记录系统日志
- OMCS ——卓尔不群的网络语音视频框架
- 网站网址前的小logo
- memcached命令和配置
- 【HDU 5808】 Price List Strike Back (整体二分+动态规划)
- hive中beeline取回数据的完整流程
- 新数据革命: 开源C#图形化爬虫引擎Hawk5发布
- redis优化