读javascript高级程序设计03-函数表达式、闭包、私有变量
一、函数声明和函数表达式
定义函数有两种方式:函数声明和函数表达式。它们之间一个重要的区别是函数提升。
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-函数表达式、闭包、私有变量的更多相关文章
- 读javascript高级程序设计00-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- 读javascript高级程序设计-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- 读javascript高级程序设计08-引用类型之Global、Math、String
一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...
- 前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器
回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callbac ...
- 读javascript高级程序设计02-变量作用域
一. 延长作用域链 有些语句可以在作用域前端临时增加一个变量对象,该变量对象在代码执行完成后会被移除. ①with语句延长作用域. function buildUrl(){ var qs=" ...
- JavaScript高级程序设计学习笔记第四章--变量、作用域和内存问题
1.变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象. 2.变量复制 如果从一个变量向另一个变量复制基本类型的值,会在 ...
- 读javascript高级程序设计01-基本概念、数据类型、函数
一. javascript构成 1.javascript实现由三部分组成: ECMAScript:核心语言功能 DOM:文档对象模型,提供访问和操作网页内容的方法和接口 BOM:浏览器对象模型,提供与 ...
- 读javascript高级程序设计16-几条函数小技巧
内容概要 作用域安全的构造函数 惰性载入函数 函数绑定 函数节流 一.作用域安全的构造函数 我们知道,当使用new操作符调用构造函数时,构造函数内部的this会指向新创建对象的实例. function ...
- 读javascript高级程序设计10-DOM
一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...
随机推荐
- 【转】SQLServerDBA十大必备工具---让生活轻松点
曾经和一些DBA和数据库开发人员交流时,问他们都用过一些什么样的DB方面的工具,大部分人除了SSMS和Profile之外,基本就没有使用过其他工具了: 诚然,SSMS和Profile足够强大,工作的大 ...
- Leetcode: Longest Repeating Character Replacement && G 面经
Given a string that consists of only uppercase English letters, you can replace any letter in the st ...
- zjuoj 3604 Tunnel Network
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3604 Tunnel Network Time Limit: 2 Secon ...
- 谨慎使用多线程中的fork
// Upon successful completion, pthread_atfork() shall return a value of zero; otherwise, an error nu ...
- SQL内联多个表
SQL多个表组合成一个表: strSql.Append(@"Select N.NotificationOptionId, S.FullName, No.Title, N.SortCode, ...
- openDatabase() chrome vivaldi Stylish
located at /Users/ruili/Library/Application Support/Vivaldi/Default/databases/ Databases.db contains ...
- 阿里云oss上传图片
1.首先我们要下载阿里云oss的sdk包:(可以下载原版的,改过的通用版在本人的百度云,嘎嘎嘎~) 2.下载好之后放到项目文件目录里面 3.要在需要的控制器引用这个sdk文件例如: include(& ...
- json学习小记
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Asp.net 头像的简单实现
1:创建数据库 Create Table ImageSave ( ID ,), Name ), img image ) 2:上传照片页关键代码 前台: <div> <asp:File ...
- (转)MySQL联表查询
资料源于网络 一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2 ...