函数表达式和闭包

针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内。写这个主要是当个笔记加总结

存在的问题请大家多多指正!

定义函数的两种方法

函数声明:

function functionName(arg0,arg1,arg2){
//函数体
}

函数表达式:

var  functionName = function(arg0, arg1, arg2){
//函数体
}

函数声明提升:函数可以先用,声明在下面自动给提到上面来

函数表达式=后面的是匿名函数,又叫拉姆达函数,他一般可以被用来当成值使用(可以用来return)

递归

函数自己调用自己就叫递归,没啥好说的。当函数赋值给另一个函数时会导致重新调用函数名称不同而调用失败

var anotherFactorial = factorial //factorial是一个递归函数
factorial = null
alert(anotherfactorial(5))//error

所以在函数内部自己调用自己的时候不要使用自己的函数名,应该用耦合度更大的arguments.callee来表示自己的函数名,例如

fucntion factorial(num){
if(num <= 1){
return 1
} else {
//此处arguments.callee代替函数名factorial
return num * arguments.callee(num-1)
}
}

闭包

总结来说就是指有权限访问另一个函数作用域中的变量的函数

常见的方式就是在一个函数内部创建另一个函数。

先看一波闭包的效果:

//creatComparisonFunction是下面要说的外层函数
var compareNames = creatComparisonFunction('name')
//compareNames在调用的就是闭包函数方法了,为什么对象能够使用方法,因为闭包返回的是一个方法
var result = compareNames({ name: 'laotie' },{ name: '6666'})

仔细的说的话在一个函数里的return出来的匿名函数就叫闭包。在作用域链中一个函数内部的函数可以访问他链后面(链后面指当前活动对象的外层,也就是内层函数外层的函数)对象的参数,然而当外面函数执行完了,里面的函数就不能再去调用外层函数的数据了,这是因为当一个函数执行完毕时,局部活动的对象就会被销毁,当外层函数执行完后里不仅内层函数被销毁,顺带着外层函数的数据也被销毁了。然而通过闭包可以实现一种效果,外层函数执行完了以后,内层函数再次调用的话还可以调用外层函数的属性。

因为太抽象了,所以书中给了一个例子:

//createComparisonFunction 就是一个外层函数,他传进来一个propertyName的参数
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
}
}
}

上面例子中return 的function就是闭包函数,闭包实现'外层函数执行完了以后,内层函数再次调用的话还可以调用外层函数的属性的'这种效果主要是因为匿名函数的作用域链中包含他的外层函数,因为匿名函数的作用域链始终引用着他外层函数的活动对象,所以除非接触匿名函数的引用,否则外层函数的活动对象会一直存在。这也引起来闭包会比较占内存,所以要慎重使用。

//跟上第一个例子:解除对匿名函数的引用
compareNames = null

javascript 函数表达和闭包的更多相关文章

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

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

  2. JavaScript函数表达式、闭包、模仿块级作用域、私有变量

    函数表达式是一种非常有用的技术,使用函数表达式可以无需对函数命名,从而实现动态编程.匿名函数,是一种强大的方式,一下总结了函数表达式的特点: 1.函数表达式不同于函数声明,函数声明要求有名字,但函数表 ...

  3. JavaScript 函数作用域和闭包

    函数作用域和闭包  词法作用域   它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定.   调用对象     ...

  4. 剖析JavaScript函数作用域与闭包

    在我们写代码写到一定阶段的时候,就会想深究一下js,javascript是一种弱类型的编程语言,而js中一个最为重要的概念就是执行环境,或者说作用域.作用域重要性体现在哪呢?首先,函数在执行时会创建作 ...

  5. Javascript ----函数表达和形参实参

    1.函数是对象,函数名实际上是函数对象的指针 1.函数声明方式 (函数声明提前) function sum(num1,num2){return num1+num2;} 2.函数表达式 var sums ...

  6. 第八章:Javascript函数

    函数是这样一段代码,它只定义一次,但可能被执行或调用任意次.你可能从诸如子例程(subroutine)或者过程(procedure)这些名字里对函数概念有所了解. javascript函数是参数化的: ...

  7. JavaScript学习总结(二)——闭包、IIFE、apply、函数与对象

    一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...

  8. JavaScript学习总结(三)——闭包、IIFE、原型、函数与对象

    一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...

  9. javaScript函数与闭包

    js中函数也是对象,具有一切对象的特征,可以作为表达式给变量赋值,可以作为函数的形参,或者函数的返回值,函数内可以嵌套函数等等,函数内以声明方式定义的函数是局部函数,用表达式声明的函数则由赋值变量的性 ...

随机推荐

  1. 07webpack--下载对应的css模块

    <!--本节 loader配置处理css样式 在src下新建css文件夹 在css下创建index.css 在main.js这个入口文件中 引入js模块 和 css杨思表是不同的 在main.j ...

  2. BeanShell实现加密解密功能

    一,在IDEA中写好加密的脚本 二,然后将整个包文件导出,生成jar包 三,将jar包文件放到jmeter的lib/ext目录下 然后在jmeter的BeanShell中引入该类,调用其中的加密方法 ...

  3. Linux命令——trap

    简介 trap是shell内置命令,它对硬件信号和其他事件做出响应.trap定义并激活信号处理过程,信号处理过程是当shell接收信号或其他特殊条件时要运行的处理过程. 语法 trap [-lp] [ ...

  4. day37_8_21表的查询

    一.语法 表的查询一般使用select关键字,配合where筛选.顺序如下: # 先后顺序 from where select 二.where约束条件 首先先建立表: create table emp ...

  5. python27期day07:基础数据类型补充、循环删除的坑、二次编码、作业题。

    1.求最大位数bit_length: a = 10 #8421 1010print(a.bit_length())结果:42.capitalize首字母变大写: s = "alex" ...

  6. zz开源 MNN:淘宝在移动 AI 上的实践

    开源 MNN:淘宝在移动 AI 上的实践   陈以鎏(离青) 阅读数:40612019 年 6 月 28 日   随着深度学习的快速发展和端侧设备算力的不断提升,原本在云端执行的推理预测工作正在部分迁 ...

  7. [LeetCode] 116. Populating Next Right Pointers in Each Node 每个节点的右向指针

    You are given a perfect binary tree where all leaves are on the same level, and every parent has two ...

  8. 关于被malloc分配内存的指针

    例如创建了一个链表指针p并为其malloc()分配了内存,那么这个指针指向的地方其实是有数据的. 你可以把p->data打印出来,会发现是一个随机值 因为只是分配内存而没有指定data的值,所以 ...

  9. Lambda 表达式已阅

    Lambda 表达式已阅 君子之间淡如水,何谓淡如水?并不时常想起,但却无处不在. 背景:This is f**king why we code? 可以让Java 代码异常简洁的Lambda 表达式, ...

  10. mysql的varchar和oracle的varchar2、nvarchar2

    mysql的varchar长度表示字符长度,一个汉字和一个英文字母的长度都是1 实例:下面name字段定义为varchar(10),可存10个汉字和10个字母 oracle的varchar2长度表示的 ...