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. java基本框架

    public class 文件名 { public static void mian(string[] args) { 自己的代码: } }

  2. C和C++中动态链接库的创建和链接(原创,装载请注明原处)

    C和C++中动态链接库的创建和链接 1.创建DLL(动态链接库)-C++方式 1.创建DLL(动态链接库-C++方式) 1.在VS(以VS2017为例)中创建DLL动态链接库. 解决方案名称为:MyD ...

  3. xmind 8 安装后启动失败(未提示错误信息)

      xmind 8 安装后启动失败   前言 家里的计算机也安装了xmind,启动之后界面显示xmind的启动图标,几秒之后启动图标消失(闪退了),然后留我一脸懵逼.想着卸载了安装一个新的应该没有问题 ...

  4. rspec测试(使用guard自动测试和spork加速测试)配置

    Gemfile文件添加rspec.guard和spork,之后执行bundle install命令 gem 'rb-readline' group :development, :test do # C ...

  5. Python旅途——简单语法

    1. 前言 在我们对环境以及pycharm安装好之后,我们就可以开始我们的Python之旅了,那么,我们学习一门语言应该如何开始呢?就像我们学习汉语一样,从abcd这些拼音学起,而对于我们Python ...

  6. Django 1.8.11 REST风格路由

    # -*- coding: utf-8 -*- """ Tencent is pleased to support the open source community b ...

  7. scrapy_redis使用介绍

    scrapy_redis是一个基于redis的scrapy组件,通过它可以快速实现简单的分布式爬虫程序,该组件主要提供三大功能: (1)dupefilter——URL去重规则(被调度器使用) (2)s ...

  8. HDU 4436 str2int

    str2int Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on HDU. Original ID: 4 ...

  9. 什么是Service Mesh?

    转至大佬宋净明的博客:https://jimmysong.io/posts/what-is-a-service-mesh/ Service mesh 又译作 “服务网格”,作为服务间通信的基础设施层. ...

  10. MITM Proxy环境搭建

    MITM_Proxy环境搭建 环境要求 系统环境要求: Ubuntu 14.04 x64,CentOS 7 x64以上版本系统(建议使用xubuntu 14.04 x64,稳定硬件要求低) Pytho ...