var foo = 1; 
function bar() { 
    if (!foo) { 
        var foo = 10; 
    } 
    alert(foo); 

bar();//解释:js没有块级作用域,if switch while等不会有块级作用域

如果你对foo的值实际上为"10"而感到诧异的话,再看一下下面这个例子:

var a = 1; 
function b() { 
    a = 10; 
    return; 
    function a() {} 

b(); 
alert(a);
发现浏览器会弹出alert(1)。
//解释:第一点是函数声明的提升会把函数的实现都提升到作用域的最顶级,上面的函数b相当于
function b() { 
  function a() {} 
    a = 10; 
    return; 
    

第二点是:这样的话,我们在b函数里面定义了一个a函数,a的作用域是在b函数的内部而非全局,这是对a的赋值相当于把a函数替换,作用域并不发生变化,相当于用var定义了一个a变量;所以在b函数外面输出a的时候只会去访问全局的a;
//var a = 1; 
function b() { 
    a = 10; 
    return; 
    function a() {} 

b(); 
alert(a);//报错a is undefined
另外:如果这里的a函数不是函数声明式定义的而是变量式定义的,变量提升而函数实现并不会提升:如下:
var a = 1; 
function b() { 
    a = 10; 
    return; 
    a=function () {} //此处的a是全局的变量

b(); 
alert(a);//10
如果是这样的话
var a = 1; 
function b() { 
    a = 10; 
    return; 
  var a=function () {} //此处的a是局部变量

b(); 
alert(a);//1
等价于这个:
var a = 1; 
function b() { 
   var a;
    a = 10; 
    return; 
  a=function () {} //此处的a是局部变量

b(); 
alert(a);//1
可以发现,声明语句中的赋值部分并没有被提升声明,只有名称被提升了。两种函数声明方式:
function test() { 
    foo(); // TypeError "foo is not a function" 
    bar(); // "this will run!" 
    var foo = function () { // function expression assigned to local variable 'foo' 
        alert("this won't run!"); 
    } 
    function bar() { // function declaration, given the name 'bar' 
        alert("this will run!"); 
    } 

test();
这个例子中,只有包含函数体的函数声明会被提升声明。foo虽然会被提升声明,但是函数体却在执行中被赋值。以上就是提升声明时机的基本概念,看起来一点也不复杂。

Name resolution order(JavaScript中名称解析顺序)

名称解析顺序有4步,一般来说,如果一个名称已经被定义了,它就不会被另一个具有同名称的属性所覆盖。这也就意味着,函数声明会比变量声明优先。并不是名称的赋值操作不会被执行,只是说声明部分被忽略了而已。有些例外:
  • 原生变量arguments特立独行,包含了传递到函数中的参数。如果自定义以arguments为命名的参数,将会阻止原生arguments对象的创建。所以勿使用arguments为名称的参数。
  • 胡乱使用this标识符会引起语法错误。
  • 如果多个参数具有相同的命名,那么最后一个参数会优先于先前的,即时这个参数未定义。

Named Function Expressions(函数命名表达式)

你可以通过函数表达式给函数命名,语法上看起来像是函数声明,实则不是。上一段代码:
foo(); // TypeError "foo is not a function" 
bar(); // valid 
baz(); // TypeError "baz is not a function" 
spam(); // ReferenceError "spam is not defined" 
 
var foo = function () {}; // anonymous function expression ('foo' gets hoisted) 
function bar() {}; // function declaration ('bar' and the function body get hoisted) 
var baz = function spam() {}; // named function expression (only 'baz' gets hoisted) 
 
foo(); // valid 
bar(); // valid 
baz(); // valid 
spam(); // ReferenceError "spam is not defined"
												

JavaScript中的作用域与函数和变量声明的提升的更多相关文章

  1. javascript中var let const三种变量声明方式

    javascript中var let const三种变量声明方式 1.var  ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...

  2. Javascript中函数及变量定义的提升

    <html> <head> <title>函数提升</title> <script language="javascript" ...

  3. JavaScript中的作用域

    很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...

  4. [转]Javascript中的自执行函数表达式

    [转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...

  5. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

  6. 【翻译】JavaScript中的作用域和声明提前

    原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译开始=== 你知道下面的JavaScript脚本执 ...

  7. JavaScript中的作用域和闭包

    首先强烈安利<你不知道的JavaScript>,JS初学者进阶必读. 对于从C++.Java等静态语言转向JavaScript的初学者(比如我)来说,JS一些与众不同而又十分要紧的特性使得 ...

  8. JavaScript中的作用域和声明提前

    [翻译]JavaScript中的作用域和声明提前 原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译 ...

  9. javascript中的立即执行函数(function(){…})()

    javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...

随机推荐

  1. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (五) 如何让窗体记录登录状态Session

    在写自动化测试的Node.js脚本时, 时常需要测试所写的case, 可能都需要去重新登录一遍,这将相当的耗时, 好在Selenium都借了Session的机制, 如果在最初的浏览器没有关闭的情况下, ...

  2. 刷票 变 IP

    刷票 变 IP

  3. bzoj 1176 Mokia(CDQ分治,BIT)

    [题目链接]  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=96974 [题意] 定义查询操作与修改操作:1 x y z 为 ...

  4. NOIP2010 引水入城

    4引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个 ...

  5. 2016"百度之星" - 复赛(Astar Round3) 1003 拍照

    拍照 思路:先静态,离线树状数组,分别统计每个点向左向右能看到的船的数量.再枚举整个区间求最大值. 应为人和船都是动态的,假设船往左走,处理每个点看到向左最大船的数量,满足动态条件.就是向左的船一开始 ...

  6. rpc,客户端与NameNode通信的过程

    远程过程:java进程.即一个java进程调用另外一个java进程中对象的方法. 调用方称作客户端(client),被调用方称作服务端(server).rpc的通信在java中表现为客户端去调用服务端 ...

  7. Ubuntu 14.04.3 LTS 配置 DNS Server

    我们目的是用一台局域网机器完成 192.168.1.113 <-->cloudshield.com的解析,指定A记录和CNAME; 0.关于Ubuntu 14.04.2 LTS 下载.安装 ...

  8. homework-02 一坑到底的最大和联通图

    你在这个作业中学到了什么?  有什么好的设计值得分享?  感想如何 (太容易 / 太难 / 太无趣)? 我觉得这套题目有点偏难,我不像大牛那样,有很多算法可以选择,我是0算法基础的,所以遇到这题我一个 ...

  9. Java网络编程(UDP协议-聊天程序)

    接收端: package WebProgramingDemo; import java.net.DatagramPacket; import java.net.DatagramSocket; publ ...

  10. HDU 4628

    这是一个大水题啊... 因为比赛时不会算复杂度耽误半天. i从0到2^n枚举集合i的所有分割两半的情况的复杂度为O(3^n),可以想象这个过程相当于是给每个位标记0,1,2(0表示不选,1,2表示两个 ...