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. react笔记汇总

    1.什么是React? a.React 是一个用于构建用户界面的 JAVASCRIPT 库. b.React主要用于构建UI,很多人认为 React 是 MVC 中的 V. c.React 起源于 F ...

  2. 01matplotlib

    一. 简介 1.概念 matplotlib:最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建. 2.作用 1)能将数据进行可视化,更直观的呈现 2)使 ...

  3. 洛谷p1049 01背包

    dp水之旅背包 题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱 ...

  4. int (*a)[10]和int *a[10]的区别

    有点晚了,放个链接,睡觉. https://stackoverflow.com/questions/13910749/difference-between-ptr10-and-ptr10

  5. 我们需要了解的五个ERP趋势

    企业的全面现代化进程伴随着ERP的发展.在2019年,预计规模较小的供应商将加大力度,双层ERP(Two-Tier ERP)将开始占据市场份额,企业也将要求更加灵活的ERP的实施方案. 该预测基于咨询 ...

  6. C第12章-----堆

    #include <stdio.h> #include <stdlib.h> //声明Person结构 //struct Person{ //    float heightI ...

  7. loadRunner之参数化,对用户名和密码进行参数化,并打印输出---实际操作:用户登录的账号用随机值来登录

    录制脚本,对用户名和密码进行参数化: Action() { web_url("WebTours", "URL=http://127.0.0.1:1080/WebTours ...

  8. Leetcode 306.累加数

    累加数 累加数是一个字符串,组成它的数字可以形成累加序列. 一个有效的累加序列必须至少包含 3 个数.除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和. 给定一个只包含数字 '0'- ...

  9. 第八届河南省程序设计大赛-B.最大岛屿0000110011000000

    最大岛屿                                                                                           时间限制: ...

  10. ESI 动态缓存技术[转载]

    任何一个Web网站的内容都是在不断更新和变化,但这并不意味这这个网站的内容就是动态内容,事实上,动态的内容是指用户每次点击 相同的链接时取的的内容是由Web服务器应用程序生成的,如常见得ASP,JSP ...