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 变量、函数提升的更多相关文章

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

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

  2. js中函数提升及var变量提示

    其中,在javascript中,函数声明及var声明的变量会得到提升.但是函数声明会先于var声明的变量被提升.即便function写在后面. 看下面的例子: var aa = 221; functi ...

  3. 【JS】函数提升变量提升以及函数声明和函数表达式的区别

    今天看js的变量提升问题,里面提到了函数提升.然后发现自己之前一直把函数声明和函数表达式弄错,导致函数提升出错 一.变量提升 console.log(a) var a=100 //undefined ...

  4. js变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级

    原文出自:http://www.cnblogs.com/xxcanghai/p/5189353.html作者:小小沧海 题目如下: function Foo() { getName = functio ...

  5. JS变量的提升详解

    此次说明的是var与function的变量提升 那么先看一段代码 <script type="text/javascript"> console.log(test); ...

  6. 解读JavaScript中的Hoisting机制(js变量声明提升机制)

    hoisting机制:javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 知识点一:javascript是没有 ...

  7. 【JavaScript高级进阶】JavaScript变量/函数提升的细节总结

    // 测试1 console.log('----------test1--------------'); console.log(global); // undefined var global = ...

  8. js变量声明提升

    1.变量提升 根据javascript的运行机制和javascript没有块级作用域这个特点,可以得出,变量会声明提升移至作用域 scope (全局域或者当前函数作用域) 顶部的. 变量声明提升至全局 ...

  9. JS变量声明提升和函数声明提升

    JS代码在执行的时候会先找出执行代码中定义的变量和函数,对其进行声明. 例1:console.log(a); var a = 4; 此时输出undefined.a变量在执行console.log(a) ...

  10. 详解js变量声明提升

    之前一直觉会认为javascript代码执行是由上到下一行行执行的.自从看了<你不知道的JS>后发现这个观点并不完全正确.先来给大家举一个书本上的的例子: var a='hello wor ...

随机推荐

  1. Xcode导入第三方库图文

    Three20这个与facebook亲戚的开源库是蜚声iPhone开发界,很多App都有它的影子,主要是其真得是功能强大.那么如何将Three20库添加到自己的项目中应用呢?一种是Python命令方式 ...

  2. C# string补位

    参考:https://www.cnblogs.com/zhangqs008/archive/2012/02/01/2341078.html //1.1.左补位 "; , 'A'); //1. ...

  3. [LOJ] #2363「NOIP2016」愤怒的小鸟

    精度卡了一个点,别人自带大常数,我自带大浮点误差qwq. 听了好几遍,一直没动手写一写. f[S]表示S集合中的猪被打死的最少抛物线数,转移时考虑枚举两个点,最低位的0为第一个点,枚举第二个点,构造一 ...

  4. mysql5.7配置

    my3306.cnf [client] port = 3306   #端口socket = /data/mysql3306/mysql3306.sock   #mysql以socket方式运行的soc ...

  5. QEMU支持的几种常见的镜像文件格式

    qemu-img支持非常多种的文件格式,可以通过"qemu-img  -h"查看其命令帮助得到,它支持二十多种格式:blkdebug.blkverify.bochs.cloop.c ...

  6. Python旅途——数据类型

    1.概要 ​ 今天跟大家分享的是数据类型,数据类型在Python中的重要程度就好比我们汉语中的拼音一样重要. 2.数据类型 1.整形 整形就像是数学中的1.2.3一样,用int来表示. a = 1 # ...

  7. [SQL]数据库中对值为数字,存储格式为varchar类型的字段进行排序

    如果要对数据库中某存储数字的列(存储类型不为int)进行排序,可以在order by 里对该列进行转换, 即如 order by cast(mycolumn as int) desc

  8. 大数据学习——yum练习安装mysql

    1. 安装mysql 服务器端: yum install mysql-server yum install mysql-devel 2. 安装mysql客户端: yum install mysql 3 ...

  9. NOIP2009T3最优贸易(Dfs + spfa)

    洛谷传送门 看到这个题,原本想先从后往前dfs,求出能到终点的点,再在这些点里从前往后spfa,用一条边上的两个城市的商品价格的差来作边权,实施过后,发现图中既有负边权,又有回路,以及各种奇奇怪怪的东 ...

  10. Foundation框架的一些实用方法:替换字符串,去空格,反转

    //定义一个可变字符串, Format后面可以跟字符串类型,也可以传入C语言的字符串数组 NSMutableString *str = [NSMutableString stringWithForma ...