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. hdu1078 记忆化搜索

    /* hdu 1078 QAQ记忆化搜索 其实还是搜索..因为里面开了一个数组这样可以省时间 (dp[x][y]大于0就不用算了直接返回值) */ #include<stdio.h> #i ...

  2. 使用spring等框架的web程序在Tomcat下的启动顺序及思路理清

    大牛请绕过,此文仅针对自己小白水平,对web程序的启动流程做个清晰的回顾. 一.使用spring等框架的web程序在Tomcat下的启动流程 1)Tomcat是根据web.xml来启动的.首先到web ...

  3. 20145317彭垚《Java程序设计》实验二

    20145317<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...

  4. FileResult,JavaScriptResult,JsonResult

    FileResult:可以响应任意文档的属性,包括二进制格式的数据,eg:图档,pdf,excel,zip,可以传入byte[],文档路径,Stream等不同的属性,让mvc将属性回传给客户端,除此之 ...

  5. shell的if else 以及大于,小于等逻辑表达式

    if ....; then .... elif ....; then .... else .... fi 大多数情况下,可以使用测试命令来对条件进行测试.比如可以比较字符串.判断文件是否存在及是否可读 ...

  6. php 分词 —— PHPAnalysis无组件分词系统

    分词,顾名思义就是把词语分开,从哪里分开?当然是一大堆词语里了,一大堆词语是什么?是废话或者名言.这在数据库搜索时非常有用. 官方网站 http://www.phpbone.com/phpanalys ...

  7. iOS新建项目文件管理规范

    当我们进入到新的公司的第一天,看到以前老员工编写的代码,找个东西累死人咧,那个抓耳挠腮的啊,一般情况下都有想揍人的赶脚. 哈哈,不忙,先想一下自己的代码!想一下自己写的代码怎么才能新来的人一眼就能看懂 ...

  8. ThreadLocal知识总结

    以前学习<Thinking in Java>时,了解过ThreadLocal,但没做笔记.现在又忘记了.嗯,要勤动笔.API中ThreadLocal的方法: public T get() ...

  9. Linux下开发Windows平台运行的程序 - MinGW

    开源不乏神人,于是有了MinGW(Minimalist GNU for Windows),又称mingw32,是将GCC编译器和GNU Binutils一直到Win32平台下,包含一系列头文件.库和可 ...

  10. C#中Attribute介绍

    什么是特性? MSDN中定义为:公共语言运行时运行添加类似关键字的描述声明,叫做Attribute,它对程序中的元素进行标注,如类型.方法.字段和属性等.attribute和Microsoft.Net ...