一、函数声明和函数表达式

定义函数有两种方式:函数声明和函数表达式。它们之间一个重要的区别是函数提升。

1.函数声明会进行函数提升,所以函数调用在函数声明之前也不会报错:

test();
function test(){
alert(1);
}

2.函数表达式不会进行函数提升,函数调用在函数声明之前的话会报错:

test(); // test is not a function
var test=function(){
alert(1);
}

二、递归函数

递归函数是通过在函数内部调用自身实现的。

①直接使用函数名进行递归调用

function f(num){
if(num==1){
return 1;
}else{
return num*f(num-1);
}
}
console.log(f(4));//
console.log(f(5));//

这种实现的缺点是,在函数内部直接写死了函数名称。如果进行如下设置就会报错:

var test=f;
f=null;
console.log(test(3));//报错, f is not a function

②通过arguments.callee解决,arguments.callee是一个指向正在执行的函数的指针。这样就避免了上述问题。

function f(num){
if(num==1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
console.log(f(4));//
console.log(f(5));//
var test=f;
f=null;
console.log(test(3));//

不过这种方式还有一个缺点,就是在严格模式下会执行失败。

添加"use strict"后执行会报错:

'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

③采用命名函数表达式可以在严格模式下成功。

"use strict";
var f=function t(num){
if(num==1){
return 1;
}else{
return num*t(num-1);
}
}
console.log(f(4));//
console.log(f(5));//
var test=f;
f=null;
console.log(test(3));//

三、闭包

闭包是有权访问另一个函数作用域内变量的函数。创建闭包的常见方式就是在一个函数内创建另外一个函数。在另一个函数内部定义的函数,会把外部函数的作用域添加到其作用域链中。

1.闭包与变量

①闭包只能取得包含函数中任意变量的最后一个值。例如:

function createFunctions(){
var result=new Array();
for(var i=0;i<10;i++){
result[i]=function(){
return i;
}
}
return result;
}
var result=createFunctions();
result[1]();//

这个方法调用传入1-10返回结果都是10,这并不符合预期。

②通过匿名函数进行改造:

function createFunctions(){
var result=new Array();
for(var i=0;i<10;i++){
result[i]=(function(num){
return num;
})(i);
}
return result;
}
var result=createFunctions();
result[2];//

改造后的运行结果符合我们的预期了。因为将i传递给num命名参数时是按值传递的。

2.闭包中的this

this变量是在运行时基于函数的执行环境绑定的。

在全局执行环境中,this指向window对象;

当函数作为某个对象的方法时,this等于那个对象;

匿名函数的执行具有全局性,this通常指向window对象。

①闭包中this实例:

var name='window';
var object={
name:"object",
getName:function(){
return function(){
return this.name;
}
}
};
object.getName()();//window

②先将闭包外部作用域中的this保存到一个闭包能访问到的变量中,这样就可以让闭包访问相应的对象了。例如:

var name='window';
var object={
name:"object",
getName:function(){
var that=this;
return function(){
return that.name;
}
}
};
object.getName()();//object

读javascript高级程序设计03-函数表达式、闭包、私有变量的更多相关文章

  1. 读javascript高级程序设计00-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  2. 读javascript高级程序设计-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  3. 读javascript高级程序设计08-引用类型之Global、Math、String

    一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...

  4. 前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器

    回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callbac ...

  5. 读javascript高级程序设计02-变量作用域

    一. 延长作用域链 有些语句可以在作用域前端临时增加一个变量对象,该变量对象在代码执行完成后会被移除. ①with语句延长作用域. function buildUrl(){ var qs=" ...

  6. JavaScript高级程序设计学习笔记第四章--变量、作用域和内存问题

    1.变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象. 2.变量复制 如果从一个变量向另一个变量复制基本类型的值,会在 ...

  7. 读javascript高级程序设计01-基本概念、数据类型、函数

    一. javascript构成 1.javascript实现由三部分组成: ECMAScript:核心语言功能 DOM:文档对象模型,提供访问和操作网页内容的方法和接口 BOM:浏览器对象模型,提供与 ...

  8. 读javascript高级程序设计16-几条函数小技巧

    内容概要 作用域安全的构造函数 惰性载入函数 函数绑定 函数节流 一.作用域安全的构造函数 我们知道,当使用new操作符调用构造函数时,构造函数内部的this会指向新创建对象的实例. function ...

  9. 读javascript高级程序设计10-DOM

    一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...

随机推荐

  1. [推荐] WordPress主题使用Google Fonts字体访问不了的解决办法

    外国人做的WordPress主题喜欢带上Google的字体,但到了咱天朝是没法访问fonts.googleapis.com的 现有数字公司出的公共资源库可以替换,把fonts.googleapis.c ...

  2. Debian系列Linux/Ubuntu 安装软件

    wps(http://community.wps.cn/download/) 优客天气(https://launchpad.net/indicator-china-weather/+download) ...

  3. java开发_读写txt文件操作

    package com.mi.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStr ...

  4. jenkins解决jenkins内存溢出问题

    在jenkins master-slave配置中,总是出现内存溢出问题,更换了机器设备仍然跑不起来: 问题如下: Status Code: 500 Exception: org.apache.comm ...

  5. ELK修炼之道

    看了ELK大半年了,现在就慢慢的总结一下对ELK的理解 参考资料 ELK stack中文指南 Elasticsearch权威指南 官方文档 Elasticsearch基础篇 此篇用于介绍Elastic ...

  6. 编写高性能Web应用程序的10个技巧

    这篇文章讨论了: ·一般ASP.NET性能的秘密 ·能提高ASP.NET表现的有用的技巧和窍门 ·在ASP.NET中使用数据库的建议 ·ASP.NET中的缓存和后台处理 使用ASP.NET编写一个We ...

  7. Azure Table storage 之改进DynamicTableEntity类为其添加动态语言扩展

    在之前的一篇文章中提到,storage类库中包含一个可以用来动态获取Azure table storage 表结构的类-DynamicTableEntity. 我们可以通过这个类,我们无需为每一个表提 ...

  8. 精通AngularJS 读书笔记(1)

    邂逅AngularJS AngularJS是采用JavaScript语言编写的客户端MVC框架,帮助开发者编写现代化的单页面应用.尤其适合编写有大量CURD操作的,具有AJAX风格的富客户端应用. 使 ...

  9. linux 用户态 内核态

    http://blog.chinaunix.net/uid-1829236-id-3182279.html 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在 ...

  10. python(九)re模块

    python中re模块提供了正则表达式相关操作. 1. 字符串匹配: .    匹配除换行符以外的任意字符 \w 匹配字符或数字或下划线或汉字 \s  匹配任意空白字符 \d 匹配数字 \b 匹配单词 ...