第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. SpringCache学习实践

    1. SpringCache学习实践 1.1. 引用 <dependency> <groupId>org.springframework.boot</groupId> ...

  2. 告诉你,Spring Boot 真是个牛逼货!

    现在 Spring Boot 非常火,各种技术文章,各种付费教程,多如牛毛,可能还有些不知道 Spring Boot 的,那它到底是什么呢?有什么用?今天给大家详细介绍一下. Spring Boot ...

  3. npm jspdf报错

    137073 warn optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.2 (node_modules\chokidar\node_modul ...

  4. [译]ASP.NET Core中使用MediatR实现命令和中介者模式

    作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9866068.html 在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何 ...

  5. 转:centos7搭建jenkins小记

    转自:https://segmentfault.com/a/1190000007086764 安装java环境 1.查看服务器版本 centos7,继续. cat /etc/redhat-releas ...

  6. 浅谈《think in java》:一 对象导论总结

    清单1. 抽象机制,面向对象程序设计方式 java所基于Smalltalk的特性表现一种纯粹的面向对象设计方式: 万物都是对象 程序是对象的集合(容器),他们通过发送消息(发送请求)来告知彼此所要做的 ...

  7. final,finally,finalize有什么区别?String, StringBuffer, StringBuilder有什么区别?Exception和Error有什么区别?

    继上篇JVM学习之后,后面将分三期深入介绍剩余JAVA基础面试题,每期3题. 题目一.final,finally,finalize有什么区别? /*请尊重作者劳动成果,转载请标明原文链接:*/ /* ...

  8. go等待N个线程完成操作总结

    第一种,基于原生带缓存的channel package main import "fmt" func main() { done := make(chan int, 10) for ...

  9. MySQL高可用之组复制技术(3):配置多主模型的组复制

    MySQL组复制系列文章: MySQL组复制大纲 MySQL组复制(1):组复制技术简介 MySQL组复制(2):配置单主模型的组复制 MySQL组复制(3):配置多主模型的组复制 MySQL组复制( ...

  10. 【转】JAVA解压.TAR.Z及.ZIP文件

     解压.ZIP文件 package app.qdupr.Method; import java.io.File; import java.io.FileOutputStream; import jav ...