美文网首页
从屌丝到架构师的飞越(JavaScript篇)-函数对象

从屌丝到架构师的飞越(JavaScript篇)-函数对象

作者: 走着别浪 | 来源:发表于2019-09-18 07:37 被阅读0次

一、介绍

这节课呢,我们来了解的是JavaScript 函数定义,前面我们已经了解了函数的基本语法,下面我们来深入的了解一下函数

JavaScript 使用关键字 function 定义函数。

函数可以通过声明定义,也可以是一个表达式。

在之前的教程中,你已经了解了函数声明的语法 :

函数声明后不会立即执行,会在我们需要的时候调用到。

分号是用来分隔可执行JavaScript语句。

由于函数声明不是一个可执行语句,所以不以分号结束。

JavaScript 变量可以是局部变量或全局变量。

私有变量可以用到闭包。

闭包就是一个函数引用另一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会增加内存消耗。

或者说闭包就是子函数可以使用父函数的局部变量,还有父函数的参数。

二、知识点介绍

1、函数表达式

2、Function()构造函数

3、函数提升

4、自调用函数

5、函数可作为一个值使用

6、函数对象

三、上课对应视频的说明文档

1、函数表达式

JavaScript 函数可以通过一个表达式定义。

函数表达式可以存储在变量中:

实例

var x = function (a, b) {return a * b};

在函数表达式存储在变量后,变量也可作为一个函数使用:

实例

var x = function (a, b) {return a * b};

var z = x(4, 3);

以上函数实际上是一个 匿名函数 (函数没有名称)。

函数存储在变量中,不需要函数名称,通常通过变量名来调用。

上述函数以分号结尾,因为它是一个执行语句。

2、Function() 构造函数

在以上实例中,我们了解到函数通过关键字 function 定义。

函数同样可以通过内置的 JavaScript 函数构造器(Function())定义。

实例

var myFunction = new Function("a", "b", "return a * b");

var x = myFunction(4, 3);

实际上,你不必使用构造函数。上面实例可以写成:

实例

var myFunction = function (a, b) {return a * b}

var x = myFunction(4, 3);

在 JavaScript 中,很多时候,你需要避免使用 new 关键字。

3、函数提升(Hoisting)

在之前的教程中我们已经了解了 "hoisting(提升)"。

提升(Hoisting)是 JavaScript 默认将当前作用域提升到前面去的的行为。

提升(Hoisting)应用在变量的声明与函数的声明。

因此,函数可以在声明之前调用:

myFunction(5);

function myFunction(y) {

return y * y;}

使用表达式定义函数时无法提升。

4、自调用函数

函数表达式可以 "自调用"。

自调用表达式会自动调用。

如果表达式后面紧跟 () ,则会自动调用。

不能自调用声明的函数。

通过添加括号,来说明它是一个函数表达式:

实例

(function () {

var x = "Hello!!";      // 我将调用自己

})();

以上函数实际上是一个匿名自我调用的函数 (没有函数名)。

5、函数可作为一个值使用

JavaScript 函数作为一个值使用:

实例

function myFunction(a, b) {

return a * b;

}

var x = myFunction(4, 3);

JavaScript 函数可作为表达式使用:

实例

function myFunction(a, b) {

return a * b;

}

var x = myFunction(4, 3) * 2;

6、函数对象

在 JavaScript 中使用 typeof 操作符判断函数类型将返回 "function" 。

但是JavaScript 函数描述为一个对象更加准确。

JavaScript 函数有 属性 和 方法。

arguments.length 属性返回函数调用过程接收到的参数个数。

6.1、arguments 对象

6.1.1、arguments是什么? 

该对象包含了函数执行时,传入的所有参数

在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们。

例如,在函数 sayHi() 中,第一个参数是 message。用 arguments[0] 也可以访问这个值,即第一个参数的值(第一个参数位于位置 0,第二个参数位于位置 1,依此类推)。

因此,无需明确命名参数,就可以重写函数:

function sayHi() {

if (arguments[0] == "bye") {

return;

}

alert(arguments[0]);

}

6.1.2检测参数个数

还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 即可。

下面的代码将输出每次调用函数使用的参数个数:

function howManyArgs() {

alert(arguments.length);

}

howManyArgs("string", 45);

howManyArgs();

howManyArgs(12);

上面这段代码将依次显示 "2"、"0" 和 "1"。

注释:与其他程序设计语言不同,ECMAScript 不会验证传递给函数的参数个数是否等于函数定义的参数个数。开发者定义的函数都可以接受任意个数的参数(根据 Netscape 的文档,最多可接受 255 个),而不会引发任何错误。任何遗漏的参数都会以 undefined 传递给函数,多余的函数将忽略。

6.1.3、模拟函数重载

用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载:

function doAdd() {

if(arguments.length == 1) {

alert(arguments[0] + 5);

} else if(arguments.length == 2) {

alert(arguments[0] + arguments[1]);

}}

doAdd(10); //输出 "15"

doAdd(40, 20); //输出 "60"

当只有一个参数时,doAdd() 函数给参数加 5。如果有两个参数,则会把两个参数相加,返回它们的和。所以,doAdd(10) 输出的是 "15",而 doAdd(40, 20) 输出的是 "60"。

虽然不如重载那么好,不过已足以避开 ECMAScript 的这种限制。

6.2、Function对象

6.2.1、Function 对象的 length 属性

如前所述,函数属于引用类型,所以它们也有属性和方法。

ECMAScript 定义的属性 length 声明了函数期望的参数个数。例如:

function doAdd(iNum) {

alert(iNum + 10);

}

function sayHi() {

alert("Hi");

}

alert(doAdd.length); //输出 "1"

alert(sayHi.length); //输出 "0"

函数 doAdd() 定义了一个参数,因此它的 length 是 1;sayHi() 没有定义参数,所以 length 是 0。

记住,无论定义了几个参数,ECMAScript 可以接受任意多个参数(最多 25 个),这一点在《函数概述》这一章中讲解过。属性 length 只是为查看默认情况下预期的参数个数提供了一种简便方式。

6.2.2、Function 对象的方法

Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法。这两个方法返回的都是函数的源代码,在调试时尤其有用。例如:

function doAdd(iNum) {

alert(iNum + 10);

}

document.write(doAdd.toString());

相关文章

网友评论

      本文标题:从屌丝到架构师的飞越(JavaScript篇)-函数对象

      本文链接:https://www.haomeiwen.com/subject/qkkeectx.html