js007-函数表达式
js007-函数表达式
本章内容
1、函数表达式的特征
2、使用函数实现递归
3、使用闭包定义私有量
定义函数的方式有两种:一:函数声明,二:函数表达式
函数声明:
|
function functionName( arg0, arg1, arg2){ //函数体 } |
|
其中function是关键字 functionName:函数名;参数 |
关于函数声明,一个重要特征是函数声明提升:执行代码之前先读取函数声明;这意味着可以吧函数声明放在调用它的语句后面
|
sayHi(); function sayHi(){ alert("Hi!"); } |
不会抛出错误因为:函数声明提升 |
函数表达式:
|
var functionName = function( arg0, arg1, arg2){ //函数体 } |
创建一个函数并将它赋值给变量functionName 匿名函数 |
理解函数声明提升的关键是理解函数声明和函数表达之间的区别。
7.1递归
递归函数时在一个函数通过名字调用自身的情况下构成的。
|
function factorial(num){ if (num <= 1) { return 1; }else{ return num * factorial(num - 1); } } |
7.2闭包
闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的最常见的方式,是:在一个函数内部创建另一个函数仍以前面的createComparisonFunction()函数为例。
|
function createComparisonFunction(propertyName){ return function(object1, object2){ var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2) { return -1; }else if (value1 > value2) { return 1; }else{ return 0; } }; } |
黑体是内部函数,它们访问了外部函数中的变量propertyName |
7.2.1 闭包与变量
因为作用链的原因,闭包只能取得包含函数中任何变量的最后一个值.而闭包所保存的是整个的变量对象,而不是某个特殊变量
|
function createFunction(){ var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function(){ return i; }; } return result; } |
表面上看,每个函数都返回自己的索引值。但是事实上每个返回的都是10因为每个函数的作用域链中都保存着createFunction()函数的活动对象,所以他们引用的都是同一个变量i |
可以通过常见一个匿名函数强制让闭包的行为符合预期:
|
function createFunction(){ var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function(num){ return function(){ return num; }; }(i); } return result; } |
定义一个匿名函数,并将执行该匿名函数的结果传给数组,匿名函数有一个参数num,是最终要返回的值。 |
7.2.2 关于this对象
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,当函数被某个兑现的的方法调用是,this等于那个对象。匿名函数的执行环境具有全局性。
|
var name = "the windos"; var object = { name: "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //"the windows" (非严格模式下) |
name: "My Object",是逗号!! 字面量方法定义对象里面的属性,用逗号隔开。定义一个对象后后分号结束。 一条执行语句之后用分号结束 |
|
var name = "the windos"; var object = { name: "My Object", getNameFunc : function(){ var that = this; return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //"My Object" |
吧外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。 |
this值可能会被意外的改变,在集中特殊情况下:
|
var name = "the windos"; var object = { name: "My Object", getNameFunc : function(){ return this.name; } }; object.getNameFunc(); //"My Object" (object.getNameFunc)(); //"My Object" (object.getNameFunc= object.getNameFunc)(); //"the windos" |
第三句是什么意思(object.getNameFunc = object.getNameFunc)(); //"the windos" |
7.2.3 内存泄露
闭包会引用包含函数的整个活动对象,其中包含着element,及时闭包不引用element包含函数的活动对象也仍然会保存一个引用,所以要把element变量设置为null,这样能够接车对DOM对象的引用,顺利地减少其引用书,确保正常收回其占用的内存。
7.3模仿块级作用域
JS没有块级作用域的概念,意味着块语句中定义的变量,实际上是包含在函数中而给语句中创建的。
|
function outputNumbers(count){ for (var i = 0; i < count; i++) { alert(i); } alert(i); //计数 } |
块级作用域(私有作用域)匿名函数的语法如下:
|
(function(){ //这里是块级作用域 })(); |
函数声明不能加圆括号,函数表达式可以添加圆括号。要把函数声明变成函数表达式可以如下做法
|
函数声明 |
函数表达式 |
|
function(){ //这里是块级作用域}();//出错 |
(function(){ //这里是块级作用域})(); |
私有作用域可以用于历史需要一些变量时:
|
function outputNumbers(count){ (function(){ for (var i = 0; i < count; i++) { alert(i); })(); alert(i); //导致错误 } |
for循环外面插入了一个私有作用域,匿名函数中定义的任何变量都会在执行结束时被销毁 |
7.4 私有变量 (举例子,还未完成)
在JS中,所有对象属性都是公有的。不过,有一个私有变量的概念。任何函数中定义的变量,都可以认为是私有变量。因为外部函数无法访问该变量
7.4.1 静态私有变量
初始化一个未声明的变量总是会创建一个全局变量,全局变量能够在私有作用域外被访问到。在严格模式下,未经声明的变量赋值会导致错误
7.4.2模块模式
模块模式是为单例创建私有变量和特权方法。单例:只有一个实例的对象。
7.4.3 增强的模块模式
在返回对象之前加入对其增强的代码。这种增强的模块模式适用那些单例必须是魔种类型的实例,同时还必须添加某些属性和方法对其加以曾强的情况
声明:该博客由http://www.cnblogs.com/lal-fighting/原创发表,未经作者允许,不得私自转载抄袭!!!
js007-函数表达式的更多相关文章
- 立即执行函数表达式(IIFE)
原文地址:benalman.com/news/2010/11/immediately-invoked-function-expression/ 译者:nzbin 也许你还没有注意到,我是一个对术语比较 ...
- JavaScript 函数表达式
JavaScript中创建函数主要有两种方法:函数声明和函数表达式.这两种方式都有不同的适用场景.这篇笔记主要关注的是函数表达式的几大特点以及它的使用场景,下面一一描述. 主要特点 可选的函数名称 函 ...
- JavaScript函数表达式、闭包、模仿块级作用域、私有变量
函数表达式是一种非常有用的技术,使用函数表达式可以无需对函数命名,从而实现动态编程.匿名函数,是一种强大的方式,一下总结了函数表达式的特点: 1.函数表达式不同于函数声明,函数声明要求有名字,但函数表 ...
- javascipt的【函数表达式】
函数表达式 在编程时,我们可以看到不管是什么类库,jquery也好,zepto也好,都会用到大量的命名函数和匿名函数表达式,本节点就是为了弄懂为何会有这些函数表达式,以及在什么情况下会使用到这些表达式 ...
- js函数表达式和函数声明的区别
我们已经知道,在任意代码片段外部添加包装函数,可以将内部的变量和函数定义"隐 藏"起来,外部作用域无法访问包装函数内部的任何内容. 例如: var a = 2; function ...
- js立即调用的函数表达式
1.多种实现 // 下面2个括弧()都会立即执行 (function () { /* code */ } ()); // 推荐使用这个 (function () { /* code */ })(); ...
- 深入理解javascript系列(4):立即调用的函数表达式
本文来自汤姆大叔 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法 ...
- 一步步学习javascript基础篇(6):函数表达式之【闭包】
回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; } //函数声明语法定义 2. var sum = funct ...
- javascript中函数声明和函数表达式浅析
记得在面试腾讯实习生的时候,面试官问了我这样一道问题. //下述两种声明方式有什么不同 function foo(){}; var bar = function foo(){}; 当初只知道两种声明方 ...
- JavaScript函数表达式
函数表达式的基本语法形式 var functionName = function(arguments){ //函数体 } 递归建议 我们通过例子来一步步说明,递归的最佳实现方式.下面是普通递归调用的例 ...
随机推荐
- js中各种宽度高度总结
offsetWidth 是对象的可见宽度,包滚动条等边线,会随窗口的显示大小改变 IE6.0.FF1.06+:offsetWidth = width + padding + borderoffsetH ...
- Go语言interface详解
interface Go语言里面设计最精妙的应该算interface,它让面向对象,内容组织实现非常的方便,当你看完这一章,你就会被interface的巧妙设计所折服. 什么是interface 简单 ...
- redis在window环境下的安装
1.下载客户端文件 地址:https://github.com/dmajkic/redis/downloads 客户端文件目录说明: 2.启动redis服务端 1.在客户端文件目录下新建一个bat文件 ...
- PS转手绘
2014-08-03 一.人物皮肤处理 复制两层图层,对背景图层隐藏,最后一层 高斯模糊 ,按住ALT创建图层蒙版, 使用画笔工具涂抹人物皮肤,眼睛不涂,把阴影和高光处抹均匀,最后应用图层蒙版,向下 ...
- sed巧用,随手记
删除文件后几行,或者前几行 方法1 都当做最后一行,来删除 for((i=1;i<4;i++)); do sed -i '$d' seq01.txt ; done 方法二 倒过来看 cat ...
- bootstrap 2.3版与3.0版的使用区别
bootstrap 2.3版与3.0版的使用区别 bootstrap已经推出了3.0的新版,看起来2.3.x版本也不会再更新了.那么bootstrap 2.3版与3.0版的区别在哪里呢?下面我们就来介 ...
- mysql-存储过程案例-存储过程中创建表和修改表数据
-- 本存储过程有特殊执行循环数量的要求,是对security_market_history表进行修正 -- 判断存储过程是否存在 drop PROCEDURE if exists proc_secu ...
- eclipse-mvn打包跳过junit测试类
修改pom.xml,在build选项加上plugins的这段如下: <build> ..... <plugins> <plugin> <groupId> ...
- 6 this的使用方法
class Person { String name; void talk() { System.out.println("my name is "+this.name); } } ...
- 【HDU 5839】Special Tetrahedron(计算几何)
空间的200个点,求出至少四边相等,且其余两边必须不相邻的四面体的个数. 用map记录距离点i为d的点有几个,这样来优化暴力的四重循环. 别人的做法是枚举两点的中垂面上的点,再把到中点距离相等的点找出 ...