在ECMAScript中,Function(函数)类型实际上是对象。每个函数也是Function类型的实例,而且都与其它引用类型一样具有属性和方法。由于是函数对象,因此函数名实际上也是一个指向函数对象的指针。

一、函数的声明方式

  函数通常是使用函数声明语法定义:

  1、普通的函数声明

  function sum(sum1,sum2){

  return sum1+sum2;

  }

  2、使用变量初始化函数

  var sum=function(){

  return sum1+sum2;

  }

  3、使用function构造函数

  var sum=new Function("sum1","sum2","return sum1+sum2");  //不推荐 因为这种会导致解析两次代码,一次解析常规ECMAScript,一次解析传入构造函数中的字符串

二、作为值类型

  因为ECMAScript中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另外一个函数,而且可以将一个函数作为另一个函数的结果返回。

  function callSomeFunction(someFunction,someArgument){

    return someFunction(someArgument);

  }

  这个函数接受两个参数。第一个参数应该是一个函数,第二个参数应该是要传递给该函数的一个值。

  function someFunction(someArgument){

    return  someArgument+100;

  }

  var result=callSomeFunction(someFunction,100);     //200

三、函数内部属性

在函数内部,有两个特殊的对象:agruments和this。其中,arguments是一个类型组对象,包含着传入函数中的所有参数。虽然arguments的主要用途是保存函数参数,但这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。

  function factorial(num){

    if(num<=1){

      return  1;

    } else {

      return num * factorial(num-1);

    }

  }

  定义阶乘函数一般用到递归算法;如果上面的代码所示,在函数有名字,而且名字以后也不会变的情况下,这样定义是没有问题的。但问题是这个函数的执行与函数名factorial紧紧耦合在一起。为了消除这种紧密耦合的现象,可以像下面这样使用arguments.callee。

  function factorial(num){

    if(num <= 1){

      return 1;

    } else {

      return num * arguments.callee(num - 1);

    }

  }

  在这个重写后的factorial()函数体内,没有再引用函数名factorial。这样,无论引用函数时使用的是什么名字,都可以保存正常完成递归调用。

  var trueFactorial=factorial;

  factorial=function(){

    return 0;

  }

  alert(trueFactorial(5));  //120

  alert(factorial(5));        //0

  函数内部另外一个对象是this,其行为与java和C#中的this大致相同。this引用的是函数据以执行操作对象,或则说函数调用语句所处的那个作用域。

  window.color = "red";

  var o = { color : "blue";};

  function sayColor(){

    alert(this.color);

  }

  sayColor();           //red

  o.sayColor = sayColor;

  o.sayColor();      //blue

  上面这个函数sayColor()是在全局作用域中定义的,它引用了this对象。由于在调用函数之前,this的值不确定,因此this可能会在代码执行过程中引用不同的对象。当在全局作用域中调用sayColor()时,this引用的是全局对象window;换句话说,对this.color求值会转换成对window.color求值,于是结果就返回了“red”。而当把这个函数赋值给对象o并调用o.sayColor()时,this引用的对象o,因此对this.color求值会转换成对o.color求值,结果就返回了“blue”;

  备注:函数名字仅仅是一个包含指针的变量而已。因此,即使是在不同的环境中执行,全局的sayColor()函数与o.sayColor()指向的任然是同一个函数。

四、函数属性和方法

  每个函数包含两个属性:length和prototype。其中,length属性表示函数希望接受的命名参数的个数:

  function sayName(name){

    alert(name);

  }

  function sum(num1,num2){

    reutrn num1 + num2 ;

  }

  function sayHi(){

    alert("hi");

  }

  alert(sayName.length);  //1

  alert(sum.length);        //2

  alert(sayHi.length);      //0

  以上三个函数,每个函数接受的命名参数个数不同。

  每个函数都包含两个非继承而来的方法:apply()和call()。这个两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。首先,apply()方法接收两个参数:一个是在其中运行函数的作用域,另外一个是参数数组。其中,第二个参数可以是Array的实例,也可以使arguments对象。

  function sum(sum1,sun2){

    return sum1 + sum2;

  }

  function callSum1(num1,num2){

    return sum.apply(this,arguments);   //传入arguments对象

  }

  function callSum2(num1,num2){

    return sum.apply(this,[num1,num2]);   //传入数组

  }

  alert(callSum1(10,10)); //20

  alert(callSum2(10,10));//20

  call()方法和 apply()方法的作用相同,他们的区别仅在于接受参数的方法不同。对于call()方法而言,第一个参数是this值没有变法,变法的是其余参数都直接传递给函数。换句话说,在使用call方法时,传递给函数的参数必须一个个的列举出来。

  function sum(sum1,sum2){

    return num1 + num2;

  }

  function callSum(num1,num2){

    return sum.call(this,num1,num2);

  }

  alert(callSum(10,10));  //20

  事实上,传递参数并非apply()和call()真正的用武之地;他们真正强大的地方是能够扩充函数赖以运行的作用域。

  window.color = "red";

  var o = { color : "blue" };

  function sayColor(){

    alert(this.color);

  }

  sayColor();                //red

  sayColor.call(this);    //red

  sayColor.call(window);  //red

  sayColor.call(o);     //blue

第十一章 Function类型的更多相关文章

  1. 第十一章 管理类型(In .net4.5) 之 管理对象的生命周期

    1. 概述 本章内容包括 管理非托管资源.使用IDisposable接口 以及 管理析构器和垃圾回收. 2. 主要内容 2.1 理解垃圾回收机制 ① 代码执行的时候,内存中有两个地方存放数据项:堆 和 ...

  2. 小红书第五章——引用类型之function类型

    有趣的函数——function类型 函数实际上是对象,每个函数都是function类型的实例,具有属性和方法. 1.函数的定义方法 1)函数声明语法 function sum(num1,num2){/ ...

  3. sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)

    第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...

  4. JS复习:第十、十一章

    第十章 NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点,但它并不是Array实例,将其转化为数组的方法: function converToArray(nodes ...

  5. jQuery第十一章

    第十一章 一.jQuery性能优化 1.使用最新版本的jQuery类库. 2.使用合适的选择器 (1)$(“#id”) :使用id来定位DOM元素是最佳提高性能的方式. (2)$(“p”) :标签选择 ...

  6. D3.js的v5版本入门教程(第十一章)——交互式操作

    D3.js的v5版本入门教程(第十一章) 与图形进行交互操作是很重要的!所谓的交互操作也就是为图形元素添加监听事件,比如说当你鼠标放在某个图形元素上面的时候,就会显示相应的文字,而当鼠标移开后,文字就 ...

  7. 第十一章 前端开发-JavaScript

    第十一章 前端开发-JavaScript 11.3.1 js引入方式 行内样式 <p id="" class="" style="" ...

  8. Flask 教程 第二十一章:用户通知

    本文翻译自The Flask Mega-Tutorial Part XXI: User Notifications 这是Flask Mega-Tutorial系列的第二十一章,我将添加一个私有消息功能 ...

  9. 第十一章 TClientDataSet

    第十一章 TClientDataSet 与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.TClientDataSet最大 ...

随机推荐

  1. ↗☻【编写可维护的JavaScript #BOOK#】第8章 避免“空比较”

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  2. Imageview使用记录

    1. imageView清除背景 原文网址:http://blog.csdn.net/lzq1039602600/article/details/40393591 两种清除 imageView的背景 ...

  3. Could not locate executable null 解决办法

    问题导读: 1.建一个MapReduce Project,运行时发现出问题:Could not locate executable null,该如何解决?2.Could not locate exec ...

  4. 【Python】python-一个class继承的小case

    #-*- coding:utf-8 -*-#定义银行类,包含属性:用户名,账户,余额:包含方法有:查询余额,存钱,取钱class BankAccount(): def __init__(self,na ...

  5. OpenGL 加载位图(BMP)贴图

    GLuint Texture[1]; HBITMAP hBMP; BITMAP BMP; glGenTextures(1, &Texture[0]); hBMP = (HBITMAP)Load ...

  6. uva11732 strcmp() Anyone?

    题意:给出多个字符串,两两配对,求总配对次数. 思路:如果两个字符串一样,ans=strlen(字符串)*2+2,如果不同,ans=公共前缀长度*2+1:用左儿子右兄弟建字典树.插入一个字符计算一次. ...

  7. 2014上海网络赛 HDU 5053 the Sum of Cube

    水 #include <stdio.h> #include <stdlib.h> #include<math.h> #include<iostream> ...

  8. 【解决】org.apache.hadoop.hbase.ClockOutOfSyncException:

    org.apache.hadoop.hbase.ClockOutOfSyncException: org.apache.hadoop.hbase.ClockOutOfSyncException: Se ...

  9. SQL Server优化相关的工具脚本

    SQL Server性能优化的一些常用脚本,适用于SQL Server 2008,更高的版本某些系统表的字段有所不同,建议参考MSDN. 死锁相关 /************************* ...

  10. C++ STL@ list 应用 (leetcode: Rotate Array)

    STL中的list就是一双向链表,可高效地进行插入删除元素. List 是 C++标准程式库 中的一个 类 ,可以简单视之为双向 连结串行 ,以线性列的方式管理物件集合.list 的特色是在集合的任何 ...