浅谈js中函数作用域和声明提前

JavaScript的函数具有两个主要特性,一是函数是一个对象,二是函数提供作用域支持,今天主要聊聊函数的作用域支持。

简单看两个概念:

  具名函数表达式

  

var add = function add (a) {
         return a
    }

这段代码描述了一个函数,称为‘具名函数表达式’。

如果省略函数表达式中的名字,它就是‘匿名函数表达式’,即匿名函数,例如

var add = function (a, b) {
    return a + b;
};

最后看下‘函数声明’

function foo() {
    // 函数体
}

函数声明只能出现在“程序代码”中,也就是说在别的函数体内或在全局。这个定义不能赋值给变量或属性,同样不能作为函数调用的参数。

//全局作用域

function foo() {}

//本地作用域

function local() {
    function bar() {}
    return bar;
}

此时的bar就是在local内,也就是在外面时访问不到的,被称之为局部作用域,那既然这样,我们看下面这段代码

var a = 1;
function aa(){
     console.log(a);
}

此时输出的结果是1,很好理解,因为在函数内部访问不到,因此会去外面寻找,直到找到为止

添加一行代码,再看看

var a = 1;
function(){
   console.log(a);
   var a =2 ;
}

此时输出结果是underfined;很诧异,没有定义之前可以在函数外部访问到,定义了反而访问不了了,实际情况是什么呢,js在函数内部定义的变量会提升至函数体顶部,但仅仅是定义,并未赋值,因此上述代码是这样的

var a = 1;
function(){
   var a;
   console.log(a);
   var a =2 ;
}

既然a定义了,但没赋值,所以console之后当然underfined啦。

既然函数声明会提升,那函数表达式会不会呢,看下面这个例子

// 全局函数
function foo() {
    alert(‘global foo‘);
}
function bar() {
    alert(‘global bar‘);
}

function hoistMe() {

    console.log(typeof foo);
    console.log(typeof bar); 

    foo();
    bar(); 

    function foo() {
        alert(‘local foo‘);
    }

    var bar = function () {
        alert(‘local bar‘);
    };
}
hoistMe();

经过上次的代码,这次就比较容易理解了,里面的函数会覆盖外面定义的函数,但是结果都是什么呢

    console.log(typeof foo); // "function"
    console.log(typeof bar); // "undefined"

    foo(); // "local foo"
    bar(); // TypeError: bar is not a function

是不是有点诧异呢,仔细想想也很容易明白

刚才说了,函数声明会提前,所以 变量foo和它的定义实现都被提前了,而且函数定义实现和书写顺序无关的,这里故意写在后面也证明了这一点。

但是函数表达式却没有这个技能,所以变量被提前,而定义却没有提前.

谢谢观看

时间: 2024-12-29 23:14:43

浅谈js中函数作用域和声明提前的相关文章

浅谈js中函数作用域问题(一)

本人学习js时间并不长,前几天,写一段js代码时,在js指定一个按钮事件的匿名函数中加入一个同级函数,具体代码可见如下: var mainOb=document.getElementById("divObject");                                        var start=document.getElementById("start"); var a=10; start.onclick=funcrion(){ functi

javascript中函数作用域和声明提前

javascript不像java等其他强类型语句,没有块级作用域(括号内的代码都有自己的作用域,变量在声明它们的代码段之外不可见)一说,但有自己的独特地方,即函数作用域. 函数作用域:变量在声明它们的函数体内以及这个函数体的任意内部函数体内是有定义的. 如下所示代码,在不同位置定义了变量i.j和k,它们都在同一个作用域内,即在函数体内均是有定义的. function test(){ var i=0; //i在整个函数体内均有定义 if(true){ var j=0; //j在整个函数体内均有定义

浅谈js中的this关键字

浅谈js中的this关键字 全局作用域中的this 函数作用域中的this 不同函数调用方法下的this 直接调用 作为对象的方法调用 作为构造函数调用 通过call或apply方法调用 嵌套函数作用域中的this 浅谈js中的this关键字 this是JavaScript中的关键字之一,在编写程序的时候经常会用到,正确的理解和使用关键字this尤为重要.接下来,笔者就从作用域的角度粗谈下自己对this关键字的理解,希望能给到大家一些启示,权当交流之用. 全局作用域中的this 本文将以作用域由

初探JavaScript(四)——JS另类的作用域和声明提前

前言:最近恰逢毕业季,千千万万的学生党开始步入社会,告别象牙塔似的学校生活.往往在人生的各个拐点的时候,情感丰富,感触颇深,各种对过去的美好的总结,对未来的展望.与此同时,也让诸多的老“园”工看完这些小年轻的文章后感触良多,不禁也要写上几笔,所以就出来了很多类似“毕业两年小记”.“毕业五年有感”…… 可能就是某篇博文的一句话,某碗心灵鸡汤就拨动了你心里的那根尘封已久的弦,让你情不自禁的点了个赞,还忍不住的要在下面评论区留下自己此刻心潮澎湃的印记. 我今天不是来送鸡汤的,鸡汤虽好,可不要贪杯哦.

浅谈javascript中的作用域

所谓的作用域,可以简单理解为一个可以读.写的范围(区域),有些js经验的同学可能会说:"js没有块级作用域",js除了全局作用域外,只有函数可以创建作用域.作用域的一个好处就是可以隔离变量. 我们通过一些例子来帮助我们理解js中的作用域. 1 alert(a); 2 var a = 1; 如果对作用域一点不了解的同学可能会说 alert的是1或者报错:但实际上是undefined: 说到这里,我们首先说一下js逐行解析代码之前做的一些准备工作, js在逐行读代码之前,会做一些“预解析”

Js中函数作用域问题

var a="111"; function fn(){ alert(this.a);} function fn2(){ var a="222" fn();//输出是111,而不是222} js中函数的作用域取决于定义它的地方而不取决于执行他的地方.

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

原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译开始=== 你知道下面的JavaScript脚本执行结果是什么吗? 1 var foo=1; 2 function bar(){ 3 if(!foo){ 4 var foo=10; 5 } 6 alert(foo); 7 } 8 bar(); 如果你对弹出的结果是"10"感到惊讶的话,那么下面这段脚本会让你晕头转向的: 1 var a=1

浅谈js回调函数

回调函数原理: 我现在出发,到了通知你”这是一个异步的流程,“我出发”这个过程中(函数执行),“你”可以去做任何事,“到了”(函数执行完毕)“通知你”(回调)进行之后的流程 例子 1.基本方法 ? 1 2 3 4 5 6 7 8 9 10 11 12 <script language="javascript" type="text/javascript"> function doSomething(callback) { // … // Call the

浅谈js中的MVC

MVC是什么? MVC是一种架构模式,它将应用抽象为3个部分:模型(数据).视图.控制器(分发器) 本文将用一个经典的例子todoList来展开 一个事件发生的过程(通信单向流动): 1.用户在视图V上与应用程序交互 2.控制器C触发相应的事件,要求模型M改变状态(读写数据) 3.模型M将数据发送到视图V,更新数据,展现给用户 在js的传统开发模式中,大多基于事件驱动的: 1.hash驱动 2.DOM事件,用来驱动视图 3.模型事件(业务模型事件和数据模型事件),用来驱动模型和模型结合 所以js