第3章 函数

3.1 什么是函数

函数:本质是一种代码的分组形式。函数的声明如下:

  <script type="text/javascript">
/*函数的声明组成:function关键字、函数名称如sum、参数、
函数体(执行的代码块)、return子句*/
function sum(a,b){
return a+b;
}
</script>

3.1.1 调用函数

调用函数的方式:在函数名后面加一对用以传递参数的括号。如调用如上sum()函数。

> var result=sum(1,3);
> result;
4

3.1.2 参数

调用时忘记传递参数值,将自动设置为undefined,如


> sum(1);//1于undefined相加
NaN
参数分为形参与实参。形参:sum(a,b);实参:sum(1,3)。
可以通过arguments变量访问函数的参数。通过arguments变量完善sum()函数,对任意数量的参数执行求和运算。代码如下:
 // arguments.length返回参数的数量
function sum1(){
var res=0;
for (var i = 0; i < arguments.length; i++) {
res+=arguments[i];
};
return res;
}

3.2 预定义函数

内建函数:parseInt()、parseFloat()、isNaN()、isFinite()、eval()等。

3.3 变量的作用域

JavaScript以函数作为作用域,不是以代码块作为作用域。

   <script type="text/javascript">
//在函数内可以访问个local
//在函数外local不存在
var global=1;
function f(){
var local=2;//声明变量没用使用var语句,该变量就会默认为全局变量
global++;
return global;
}
f();//
f();//
local;// local is not defined
</script>

变量提升

     <script type="text/javascript">
//函数域优先于全局域,局部变量a会覆盖和它同名的全局变量
//被提升的只有函数的声明
var a=123;
function f(){
alert(a);//undefined
var a=1;
alert(a);//
}
/*
等价于:
var a=123;
function f(){
var a;
alert(a);//undefined
a=1;
alert(a);// 1
}
*/
f();
</script>

3.4 函数也是数据

函数也是数据,可以把一个函数赋值给一个变量。

函数表达式

 <script type="text/javascript">
//函数标识记法 函数表达式
var f=function (){
return 1;
};
//函数声明
function f1(){
return 1;
}
</script>

函数作为数据的特点:

1>包含的是代码        2>可执行的

var sum=function(a,b){return a+b};
var add=sum;
typeof add; //"fucntion"
add(1,2); //

3.4.1 匿名函数

<script type="text/javascript">
var f=function (a){
return a;
}
</script>

用法:1>作为参数传递给其它函数       2>执行某些一次性任务

3.4.2 回调函数

如果将函数A传递给函数B,并由B来执行函数A,A就成为一个回调函数.

 <script type="text/javascript">
// 如果将函数A传递给函数B,并由B来执行函数A,A就成为一个回调函数
function add(a,b){
return a()+b();
}
function one(){
return 1;
}
function two(){
return 2;
}
add(one,two);//
//可是使用匿名函数(函数表达式),作为目标函数的参数
add(
function(){return 1;},
function(){return 2;}
); // 3
</script>

回调函数的优势:

1>在不做命名的情况下传递函数(节省变量名的使用)

2>将一个函数的调用操作委托给另一个函数(节省代码的编写工作)

3>有助于提升性能

3.4.3 回调示例

先将函数的三个参数分别乘以2,在加1。代码如下:

  <script>
//编写一个函数,将其所有的参数乘以2
// function multipleByTwo(a,b,c){
// var i,ar=[];
// for (var i = 0; i < 3; i++) {
// ar[i]=arguments[i]*2;
// }
// return ar;
// }
//函数的参数加1
function addOne(a){
return a+1;
}
// 如果要实现三个元素在两个函数之间传递,先分别乘以2在加上1
// 1.可以定义一个数组,来存储第一步的结果
/*
var myarr=[];
myarr=multipleByTwo(21,33,2);
for (var i = 0; i < 3; i++) {
myarr[i]=addOne(myarr[i]);
};
myarr;
*/
// 2.使用回调函数
function multipleByTwo(a,b,c,callback){
var i,ar=[];
for (var i = 0; i < 3; i++) {
ar[i]=callback(arguments[i]*2);
};
return ar;
}
// multipleByTwo(1,2,3,addOne); //[3, 5, 7] // 可以使用匿名函数来代替addOne(),节省全局变量
multipleByTwo(1,2,3,function(a){
return a+1;
}); //[3, 5, 7]
</script>

3.4.4 即时函数

函数在定义后立即调用。

 <script type="text/javascript">
//第二个函数起着立即调用的作用
(
function (){
alert('a');
}
)();
//或者第一对括号闭合在第二对之后
(function(){
alert('a');
}
());
//可以在第二个括号中传递参数
(
function (name){
alert('hello '+name+' !');
}
)('dude');
</script>

3.4.5 内部(私有)函数

在一个函数内部定义另一个函数。

  <script type="text/javascript">
function outer(param){
function inner(a){
return a*2;
};
return 'The result is '+inner(param);
};
outer(2);// "The result is 4"
inner(2);// inner is not defined
</script>

使用私有函数的好处:

有助于确保全局名字空间的纯净性

确保私有性—只将一些必要的函数暴露出去

3.4.6 返回函数的函数

  <script type="text/javascript">
function f1(){
alert('a');
return function (){
alert('b');
};
}
f1()();// 先执行 alert('a');再执行 alert('b');
</script>

3.4.7 能重写自己的函数

 <script type="text/javascript">
function a(){
alert('sa');
a=function (){
alert('qq');
};
}
a() //第一次调a时是sa
a() //第二次调a时是qq
</script>

3.5 闭包

3.5.1 作用域链

 <script type="text/javascript">
var a=1;
function f(){
var b=2;
return a;
};
f();// 1 在函数内部a、b都是可见的
b;// b is not defined 在函数外部a是可见的、b则不可见。
</script>

3.5.1 利用闭包突破作用域链

3.5.1.1 闭包#1

 <script type="text/javascript">
//返回函数形式的闭包
var a='glocal variable';
var F=function(){
var b='local variable';
var N=function (){
var c='inner variable';
return b;
}
return N;
};
b; // b is not defined b在全局函数中不可见
F();/*返回:function (){
var c='inner variable';
return b;
}*/
F()(); // 返回"local variable" 通过返回函数的闭包使b在全局空间中可见
</script>

3.5.1.2 闭包#2

     <script type="text/javascript">
//通过全局函数的占位符,使使局部空间和全局空间连通,实现闭包
var inner;
var F=function (){
var b="local variable";
var N=function(){
return b;
};
inner=N;
};
F(); //undefined
inner();//"local variable" //如果只执行inner();
inner(); // inner is not a function
</script>

3.5.1.3 闭包#3

     <script type="text/javascript">
//以参数形式形成闭包、
function F(param){
var N=function(){
return param;
}
param++;
return N;
}
var inner=F(111);
inner(); //
</script>

JavaScript面向对象编程指南(三) 函数的更多相关文章

  1. 《JavaScript面向对象编程指南(第2版)》读书笔记(一)

    目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...

  2. 《JavaScript面向对象编程指南》读书笔记①

    概述 JavaScript快忘完了,想看一本专业书拾遗,所以看了这本<JavaScript面向对象编程指南>. 个人觉得这本书讲的很透彻很易懂,一些原来有疑惑的地方在这本书里面豁然开朗,看 ...

  3. 闭包初体验 -《JavaScript面向对象编程指南》

    下面是我对闭包的理解:(把他们整理出来,整理的过程也是在梳理) 参考<JavaScript面向对象编程指南> 1.首先,在理解闭包之前: 我们首先应该清楚下作用域和作用域链 作用域:每个函 ...

  4. 《JavaScript面向对象编程指南(第2版)》读书笔记(二)

    <JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...

  5. 《JavaScript面向对象编程指南》读书笔记②

    概述 <JavaScript面向对象编程指南>读书笔记① 这里只记录一下我看JavaScript面向对象编程指南记录下的一些东西.那些简单的知识我没有记录,我只记录几个容易遗漏的或者精彩的 ...

  6. Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)

    Javascript面向对象编程(三):非构造函数的继承   作者: 阮一峰 日期: 2010年5月24日 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现&quo ...

  7. JavaScript 面向对象编程(三):非构造函数对象的继承

    JavaScript 面向对象编程(三):非构造函数对象的继承 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese ...

  8. JavaScript 面向对象编程(三)如何写类和子类

    在JavaScript面向对象编程(一)原型与继承和JavaScript面向对象编程(二)构造函数和类中,我们分别讨论了JavaScript中面向对象的原型和类的概念.基于这两点理论,本篇文章用一个简 ...

  9. [已读]JavaScript面向对象编程指南

    又是一个忽悠人的书名,其实这本书的花了大量内容阐述JS的基础语法,BOM,DOM,事件,ajax(这个和很多js书一样).最后一章则是编程模式与设计模式. 我觉得与面向对象没多大关系,要算的话,pro ...

随机推荐

  1. dubbo实用知识点总结(二)

    1. 参数验证 2. 结果缓存 3. 泛化引用 客户端没有对应接口类的情况,可以直接调用 4. 泛化实现 5. 回声测试 用于检测服务是否可用 6. 上下文信息 7. 隐式传参(不常用) 8. 异步调 ...

  2. 记录python题

    def mone_sorted(itera): new_itera = [] while itera: min_value = min(itera) new_itera.append(min_valu ...

  3. H5拖动实现代码

    原理以后有空再说现在嘛先上代码.... ;} html,body { width: 100%; height: 100%; ; } #dragBoxContainer{ width: 150px; p ...

  4. Google Chrome 书签导出并生成 MHTML 文件

    目的 因为某些原因需要将存放在 Google Chrome 内的书签导出到本地,所幸 Google Chrome 提供了导出书签的功能. 分析 首先在 Google Chrome 浏览器当中输入 ch ...

  5. 课程回顾-Structuring Machine Learning Projects

    正交化 Orthogonalization单一评价指标保证训练.验证.测试的数据分布一致不同的错误错误分析数据分布不一致迁移学习 transfer learning多任务学习 Multi-task l ...

  6. crontab的使用笔记

    1 crond简介crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cron ...

  7. 【转载】LINUX 和 WINDOWS 内核的区别

    LINUX 和 WINDOWS 内核的区别 [声明:欢迎转载,转载请注明出自CU ACCESSORY http://linux.chinaunix.net/bbs/thread-1153868-1-1 ...

  8. 项目实战3—实现基于Keepalived+LVS的高可用集群网站架构

    实现基于Keepalived高可用集群网站架构 环境:随着业务的发展,网站的访问量越来越大,网站访问量已经从原来的1000QPS,变为3000QPS,目前业务已经通过集群LVS架构可做到随时拓展,后端 ...

  9. man nfsd(rpc.nfsd中文手册)

    本人译作集合:http://www.cnblogs.com/f-ck-need-u/p/7048359.html rpc.nfsd() System Manager's Manual rpc.nfsd ...

  10. Perl:undef类型和defined()函数

    undef和defined()函数 undef表示的像是数据库中的"null".它表示空,啥也没有,是完全未定义的.这不等于字符串的空,不等于数值0,它是另一种类型. 在某些时候, ...