js中函数也是对象,具有一切对象的特征,可以作为表达式给变量赋值,可以作为函数的形参,或者函数的返回值,函数内可以嵌套函数等等,函数内以声明方式定义的函数是局部函数,用表达式声明的函数则由赋值变量的性质决定是局部还是全局的。函数内部使用var定义的局部变量只能在函数内部进行访问,在函数调用完成后被释放,从这点,可以模拟私有变量,块状作用域等。

1.javaScript函数定义

js中函数定义有两种方法:函数声明和函数表达式,函数声明可以进行函数声明提升,函数表达式则不会。

2.闭包

闭包是指有权访问另一个函数作用域中的变量的函数,和匿名函数是不同的概念。只不过其常见的创建方式,就是在一个函数内部创建另外一个函数。

对于一个闭包来说,其作用域链按照搜索顺序包括:闭包的活动对象——>闭包所在函数的活动对象——>全局活动对象。作用链上所有的活动对象,都能够在闭包内访问到。

关于闭包,需要注意以下几点:

1)闭包只能包含外部函数中任何变量的最后一个值,如下所示:

function createFunctions(){
    var result=new Array();
    ;i<;i++){
        result[i]=function(){
            return i;
        }
    }
    return result;
}

var result=createFunctions();
alert(result[]());

此时的返回值是10,而非想要的0.可以通过创建另一个匿名函数让闭包的行为符合预期。

function createFunctions(){
    var result=new Array();
    ;i<;i++){
        result[i]=(function(num){
            return function(){
                return num;
            }
        })(i);
    }
    return result;
}

var result=createFunctions();
alert(result[]());

经过上述重写后,函数能够返回各自不同的索引值。此时,没有把闭包直接赋值给数组,而是定义了一个匿名函数,并将该匿名函数调用的结果幅值给数组。

2)匿名函数的执行环境具有全局性,因此this对象通常指向window。每个函数在调用时候都会自动取得两个特殊变量:this和arguments;因为变量的搜索从闭包内部的活动对象开始,因此永远不可能直接访问到外部函数中的这两个变量,如果需要访问,需要将外部作用域中的this/arguments保存在一个闭包能够访问的变量中。

3)利用闭包可以模拟块状作用域

javascript没有块状作用域,只有函数级作用域和全局作用域,但可以使用匿名函数来模拟块状作用域。

(function(){
    //这里是块状作用域
})();

如:

(function(){
    ; i >= ; i--) {
        alert(i);
    }
})();

在很多人参与开发的大型项目中,这种技术通常在全局作用域中被用在函数外部,从而限制向全局作用域添加过多的变量和函数。

4)由于闭包会包含其他函数的作用域,因此会比其他函数占用更多的内存,因此,除非必要,否则尽量不要使用闭包。

3.私有变量

私有变量:javascript任何函数中定义的局部变量,内部内部定义的其他函数,函数参数都是无法从外部访问的,因此被称为私有变量。

特权方法:能够访问私有变量和私有函数的公有方法称为特权方法。在函数内部创建闭包,那么闭包可以通过自己的作用域链访问外部函数的私有变量,利用这一点,可以创建特权方法。

特权方法一般有两种模式:

1)在构造函数中定义特权方法,将函数表达式赋值给this对象的属性。其问题是不能实现函数的复用。基本模式如下:

function Person(){
    var name="bobo";
    function privateMethod(){
        return false;
    }
    this.publicMethod=function(){
        alert(name);
        return privateMethod;
    }
} 

var person1=new Person();
person1.publicMethod();

2)在私有域定义特权方法:在私有作用域中,首先定义私有变量和私有函数,之后用表达式的形式定义构造函数和公有方法,构造函数赋予的变量不能使用var修饰,因此可以在私有域外面访问到,公有方法在构造函数对应的原型中定义。

(function(){
    var name="bobo";
    //没有使用var关键字,因此Person对象是一个全局变量,可以在私有作用域之外访问到
    Person=function(value){
        name=value;
    };
    Person.prototype.setName=function(newValue){
        name=newValue;
    };
    Person.prototype.getName=function(){
        return name;
    };
})();
console.log("main function");
var person1=new Person("bobo");
person1.setName("leishao");
alert(person1.getName());

javaScript函数与闭包的更多相关文章

  1. JavaScript函数、闭包、原型、面向对象

    JavaScript函数.闭包.原型.面向对象 断言 单元测试框架的核心是断言方法,通常叫assert(). 该方法通常接收一个值--需要断言的值,以及一个表示该断言目的的描述. 如果该值执行的结果为 ...

  2. JavaScript 函数之 ------------------ 闭包

    谈到闭包,人们常常会把匿名函数和闭包混淆在一起.闭包是指由权访问另一个函数作用域中的变量的函数.创建闭包的常见方式,就是在一个函数内部创建另一个函数,仍以前面的 createComparisonFun ...

  3. JavaScript函数及闭包

    前面一片文章讲到过一点函数,了解到每声明一个函数就会产生一个作用域.而外面的作用域访问不了里面的作用域(把里面的变量和函数隐藏起来),而里面的可以访问到外面的.对于隐藏变量和函数是一个非常有用的技术. ...

  4. javascript函数闭包(closure)

    一,首先感受下javascript函数的闭包 二,闭包 1,定义:闭包就是能够读取其他函数内部变量的函数,由于在javascript语言中,只有在函数内部的子函数才能够读取局部变量,因此可以把闭包简单 ...

  5. JavaScript函数之作用域 / 作用链域 / 预解析

    关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...

  6. JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)

    1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...

  7. 深入理解javascript函数参数与闭包(一)

    在看此文章,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为这篇文章或多或少会涉及函数基础的内容,而基础内容,我放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识 ...

  8. 深入理解javascript原型和闭包(2)——函数和对象的关系

    上文(理解javascript原型和作用域系列(1)——一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; co ...

  9. JavaScript中的闭包和匿名函数

    JavaScript中的匿名函数及函数的闭包   1.匿名函数 2.闭包 3.举例 4.注意 1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没 ...

随机推荐

  1. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  2. AngularJS系列:表单全解(表单验证,radio必选,三级联动,check绑定,form提交验证)

    一.查看$scope -->寻找Form控制变量的位置 Form控制变量 格式:form的name属性.input的name属性.$... formName.inputField.$pristi ...

  3. git命令常见问题总结

    1.git如何放弃所有本地修改 git checkout . #本地所有修改的.没有的提交的,都返回到原来的状态 git stash #把所有没有提交的修改暂存到stash里面.可用git stash ...

  4. Frenetic QuickInstall

    Frenetic a family of network programming languages 官方网站:Frenetic Github:Frenetic QuickInstall 第一步,先安 ...

  5. Javascript 笔记与总结(2-3)Javascript 运算符、控制结构与对象操作

    [连接运算符 + ] <script> console.log(1+2+'a'+3+4); </script> 输出: 3a34 [逻辑运算符]返回的是最早能判断表达式结果的那 ...

  6. TextView实现圆角效果

    自定义一个Xml样式: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android ...

  7. 专家来了-提测-改bug-上线10号

    集成那天,同事帮忙改了三个bug, 适配ios6约束,方法被调用两次, 郑晓杨吃饭,好像还欠我钱呢 Product-archive  打包 ------------------------------ ...

  8. java 形参实参

    java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清. (一)基本数据类型:传值,方法不会改变实参的值. public class TestFun { public static v ...

  9. 【转】Xamarin.Android 入门之:Xamarin+vs2015 环境搭建

    Xamarin.Android 入门之:Xamarin+vs2015 环境搭建   一.前言 此篇博客主要写了如何使用搭建xamarin开发的环境,防止我自己万一哪天电脑重装系统了,可以直接看这篇博客 ...

  10. Summary of java stream classes

    Java’s stream classes are good for streaming sequences of bytes, but they’re not good for streaming ...