在Javascript中没有类的概念,函数就是第一类对象。
函数就是对象,主要的表现形式有:
1. 函数可以在运行时创建,也可以在运行的过程中创建。
2. 函数可以被分配给其他变量,可以将它们的引用复制给其他变量。
3. 函数可以作为参数传递给其他函数,且还可以作为其他函数的返回值返回。
4. 函数可以有自己的属性和方法。
本文将重点讨论函数作为返回值的形式。
例如:
var setup = function()
{
//函数setup的私有变量
var count = 0;
//返回函数访问私有变量
return function()
{
return (count += 1);
};
};
//外部调用返回函数
var next = setup();
alert(next()); //1
alert(next()); //2
alert(next()); //3
alert(next()); //4
通过以上代码,可以看到2个现象:
1. 变量count是函数setup的私有变量,外部函数是无法直接访问的,但是我们可以通过函数setup的内部匿名函数访问。如果我们将这个内部函数返回,外部调用该函数的时候就可以间接访问函数setup的私有变量。
2. 函数setup的私有变量count看起来像一个静态变量,每次调用都可以在上一次调用的基础上递增1。
现象1:在Javascript中,函数有两个特别的特征,一是前面说过的函数就是对象,二是函数提供局部作用域。这和Java中{}提供变量作用域是有区别的。
Javascript中的作用域链访问模式:
//全局作用域
var global = "global";
function outer()
{
//函数outer的作用域
var outer_v = "outer";
alert(global); //global,能访问全局作用域的变量
alert(inner); //undefined,不能访问内部函数作用域的变量
var inner = function()
{
//函数inner的作用域
var inner_v = "inner";
alert(outer_v); //outer,能访问外部函数作用域的变量
}
}
alert(outer_v); //undefined, 不能访问oute函数作用域的变量。
以上代码就是为了说明Javascript语言特有的“链式作用域”结构(chain scope)。即子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
现象2:为什么函数setup的私有变量count的表现好似Java中的静态变量?
var next = setup();
不难理解,这句话调用之后,我们创建了一个全局变量next指向了函数setup的内部函数,所以setup的内部函数将一直存在于内存中,不会被垃圾回收器回收。而内部函数的存在是依赖外部函数setup的,所以setup也会一直存在于内存中而不被销毁。所以其私有属性的值不会被重置。特别注意,Javascript中函数不是类,是第一类对象,归根结底是对象,相当于内存中存在一个不被销毁的对象,所以该对象的属性不会被改变,这和Java中的静态变量是有区别的。
可以看出,随意使用返回函数是很消耗性能的,因为这些函数对象将一直存在于内存中。
其实以上阐述的这种返回函数的模式,就是Javascript中所谓的闭包。
闭包的概念:
官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
我的理解是,闭包就是在函数外部使用函数内部的返回函数。
也就是说:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
闭包的作用主要就是为了保护私有变量。
使用闭包的注意事项:
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
2.由于Javascript特殊的作用域链,闭包会在父函数外部,改变父函数内部变量的值。
分享到:
相关推荐
在讨论JavaScript编程语言时,匿名函数和闭包是两个重要的概念,它们在函数式编程和模块化代码设计中扮演着核心角色。匿名函数是没有具体名称的函数,它们可以是独立的,也可以是表达式的一部分,通常用于定义临时...
理解函数的原型链和闭包对于深入掌握JavaScript至关重要。 首先,让我们看看函数的定义方式。在JavaScript中,我们可以使用`function`关键字直接定义函数,如`function fn(a, b) {}`。此外,函数也可以通过赋值语句...
### JavaScript基础知识点概述 #### 一、函数表达式与函数声明 JavaScript中定义函数主要分为函数声明和函数...通过理解这些基础知识点,可以更好地运用JavaScript中的函数表达式和闭包来编写高效、可维护的代码。
闭包是ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下...
JavaScript中的函数闭包是一个重要的概念,它涉及到函数的作用域、变量持久化以及内存管理等多个方面。闭包的本质是在函数内部创建另一个函数,使得内部函数能够访问并操作外部函数的局部变量,即使外部函数已经执行...
在闭包中,`this`的指向取决于调用上下文。在上述的`getUserFunction`示例中,`this`在闭包内指向的是`window`,而不是`obj`,因为闭包不是一个对象的方法。如果想让`this`指向`obj`,可以使用`.call`或`.apply`方法...
**匿名函数**和**闭包**都是JavaScript中非常强大的特性。通过灵活运用这些概念,可以编写出更加高效和可维护的代码。然而,需要注意的是,由于闭包会导致函数的作用域被持续保留,因此过度使用闭包可能会导致内存...
在JavaScript中,匿名函数、函数直接量和闭包是三种非常重要的概念,它们在编程实践中有着广泛的应用。让我们逐一深入探讨这些概念。 1. **匿名函数**: 匿名函数是指没有名字的函数,通常作为表达式的一部分存在...
JavaScript中的函数和闭包是其核心特性之一,它们在编程中扮演着至关重要的角色。首先,我们要理解函数在JavaScript中的地位。JavaScript是一种基于原型的动态类型语言,它允许函数成为一等公民,也就是说,函数可以...
js高级中的函数之闭包函数全解与应用场景(循环闭包,定时器,面试题)
JavaScript中的匿名函数和闭包是两个非常重要的概念,它们在函数式编程和模块化开发中起着关键作用。 首先,让我们来理解匿名函数。匿名函数,顾名思义,是没有名称的函数。在JavaScript中,我们可以直接定义一个不...
在JavaScript函数式编程中,闭包是一个非常重要的概念。闭包是指有权访问另一个函数作用域中变量的函数。由于JavaScript的作用域链,闭包能够访问到函数定义时的外部变量,即使外部函数已经执行结束。闭包通常用于...
深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系
在JavaScript中,闭包(Closure)是一个极其关键的概念,它使得内部函数能够访问到其外部函数的作用域内的变量,即使外部函数已经执行完毕。这一特性是基于JavaScript的函数作用域规则以及函数本身可以作为值进行...
这意味着闭包可以访问定义时的作用域,即使函数执行完毕之后,闭包中的变量也不会立即销毁,从而可以实现封装私有变量或保持变量状态。 闭包有如下几个特点: 1. 函数内部可以访问外部函数的作用域。 2. 闭包可以...
本篇文章主要探讨JavaScript函数式编程中的一个重要概念——闭包(closure)。闭包是一种特殊的函数,它能记住其定义时的作用域,即使在函数执行完毕后,仍然可以访问到该作用域内的变量。在JavaScript中,每个函数...