在上一篇 JavaScript的三种函数定义方式, 我们提到在 JavaScript 语言里, 函数也是对象, 函数既然是对象就一定有对应的属性和方法, 本篇来讲讲函数的属性和方法。
函数的内部属性
在函数内部有两个特殊的属性: arguments 和 this
1)arguments对象
Javascript并没有重载函数的功能, 但是Arguments对象能够模拟重载。arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。arguments对象不是一个 Array。它类似于Array,但除了长度之外没有任何Array属性。
它引用着函数的实参,可以用数组下标的方式”[]”引用arguments的元素。arguments.length为函数实参个数,arguments.callee引用函数自身。
1 | person('heeloo', 'word', 'up8', 'Felix Cao'); |
阶乘函数(Factorial)
1 | function factorial (num){ |
定义阶乘函数一般都会用到递归算法,如上面代码所示,在有函数名字,并且函数名字以后也不会改变的情况下,这种定义是没有问题的,但是这个函数的执行与函数名factorial紧紧的耦合在一起,为了消除这种紧密耦合现象,可以使用arguments.callee
1 | function factorial (num){ |
重写后的factorial()函数的函数体内,没有再引用函数名factorial。这样即使改变函数名字,都可以保证正常完成递归调用.
2) this, 请移步JavaScript中的this绑定/指向
函数的属性
1). length属性
在函数内部属性部分我们讲到arguments对象的length属性表示实参个数,而函数的length属性则表示形参个数
1 | function person(name, age) { |
2). name属性
函数定义了一个非标准的name属性,通过这个属性可以访问到给定函数指定的名字,这个属性的值永远等于跟在function关键字后面的标识符,匿名函数的name属性为空
1 | //IE11-浏览器无效,均输出undefined |
[注意]name属性早就被浏览器广泛支持,但是直到ES6才将其写入了标准,ES6对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名
1 | var func1 = function () {}; |
如果将一个具名函数赋值给一个变量,则ES5和ES6的name属性都返回这个具名函数原本的名字
1 | var bar = function baz() {}; |
Function构造函数返回的函数实例,name属性的值为“anonymous”
1 | (new Function).name // "anonymous" |
bind返回的函数,name属性值会加上“bound ”前缀
1 | function foo() {}; |
3). prototype属性
每一个函数都有一个prototype属性,这个属性指向一个对象的引用,这个对象称做原型对象(prototype object)。每一个函数都包含不同的原型对象。将函数用做构造函数时,新创建的对象会从原型对象上继承属性. 关于prototype属性请移步 JavaScript原型、原型对象、隐式原型
函数的方法
每个函数都有call(),apply(), bind()三个方法,他们来源于Function.prototype.call(),Function.prototype.apply(), Function.prototype.bind(), 上文提到,在JavaScript 语言里, 函数也是对象,每个函数都是 Function 类的实例,而call、apply和bind是Function类自带的三个方法。 想了解更多请移步JavaScript函数的call/apply/bind方法
toStrint方法
函数的toString方法返回一个字符串,内容是函数的源码。
1 | function add(x,y) { |