[笔记]Function类型

来源:互联网 发布:qq软件下载 编辑:程序博客网 时间:2024/05/16 10:02

一、Function类型-语法

函数声明:
function sum(num1, num2) {
return num1+num2;
}

函数表达式:
var sum = function(num1, num2) {
return num1+num2;
}

构造函数:
var sum = new Function(“num1”, “num2”, “return num1+num2”);//不推荐

注:

  • 1、使用函数表达式定义函数时,没有必要使用函数名——通过变量sum即可引用函数。
  • 2、函数末尾有一个分号。
  • 3、Function构造函数可以接收任意数量的参数,但最后一个参数始终都被看成是函数体,而前面的参数则枚举出了新函数的参数。不推荐使用!因为这种语法会导致两次的代码解析而影响性能。
  • 4、函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同。换句话说,一个函数可能会有多个名字。

例如:
这里写图片描述
上述例子中,使用不带圆括号的函数名是访问函数指针,而非调用函数。anotherSum和sum指向了同一个函数,即使sum设置为null,但仍然可以正常调用anotherSum()。

二、没有重载(深入理解)

例1:两个同名函数,后面的函数覆盖了前面的函数。
这里写图片描述

例2:与例1代码没什么区别。在创建第二个函数时,实际覆盖了引用第一个函数的变量addSomeNumber。
这里写图片描述

三、函数声明与函数表达式

函数声明和函数表达式的区别:
解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);
函数表达式,必须等到解析器执行到它所在的代码行,才会被真正解释执行。

例1:
这里写图片描述
以上代码正常运行,是因为即使申明函数的代码在调用它的代码后面,JavaScript引擎也能把函数声明提升到顶部。

例2:
这里写图片描述
上面代码之所以运行错误,原因是在执行到函数所在语句之前,变量sum中不会保存有对函数的引用。由于第一行代码会导致错误,实际上不会执行到下一行。

四、作为值的函数

因为函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传给另一个函数,也可以将一个函数作为另一个函数的结果返回。
例1:
这里写图片描述

例2:
这里写图片描述

五、函数的内部属性

在函数内部,有两个特殊的对象:arguments 和 this。

1、arguments:一个类数组对象,包含着传入函数中的所有参数。这个对象有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
例1(经典的阶乘函数):

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

例2:
这里写图片描述

这里写图片描述
在例2中,如果像原来的factorial()那样不使用arguments.callee,调用trueFactorial()就会返回0.

2、this:引用的是函数据以执行的环境对象—或者说是this值(在网页的全局作用中调用函数时,this对象引用的就是window)。
例3:

window.color = "red";var o = {color: "blue"};function sayColor() {    alert(this.color);}sayColor();    //"red"-引用的是windowo.sayColor = sayColor;o.sayColor();    //"blue"

当函数赋值给对象o,并调用o.sayColor()时,this的引用对象就是对象o,因此对this.color求值会装换成o.color求值。

六、函数的属性和方法

每个函数都包含两个非继承而来的方法:apply()和call()。这两个函数的用途都是在特定的作用域中调用函数,实际上等于先设置函数体内this对象的值。

apply()方法:接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组。其中,第二个参数可以是Array的实例,也可以是arguments对象。

call():与apply()方法作用相同,区别仅在与接收参数不同。它的第一个参数是this值没有变化,变化的是其余参数都直接传递给函数,换句话说,传递给函数的参数必须逐个列举出来。

使用这两个方法的最大好处是,不需要与方法有任何的耦合关系。

0 0