第一章:深入了解函数的属性和方法
知识点
- 函数也是对象
- 对象成员包括属性和方法
1. 函数对象的属性和方法详解
arguments
属性:
- 属性值: 对象
- 这个参数,只有函数内部使用,在调用时,才有意义
- 调用函数的实参列表,是一个类似数组的对象,但不是数组
-
argument[0]
..: 访问调用的实参 -
arguments
属性:-
argument.length
: 实参数量 -
argument.callee
: 被调用的函数体,即自身的引用
-
- 示例:
function f(m,n) {
console.log(arguments)
console.log(arguments.callee);
console.log(arguments.length);
for (var i = 0; i < arguments.length; i += 1) {
console.log(arguments[i]);
}
}
f(1,2,3);
/*
arguments 对象返回内容:
0: 1
1: 2
2: 3
callee: ƒ f(m,n)
length: 3
Symbol(Symbol.iterator): ƒ values()
__proto__: Object
---------------------------------------------------------------------
arguments.callee 返回值:
f(m,n) {
console.log(arguments)
console.log(arguments.callee);
console.log(arguments.length);
for (var i = 0; i < arguments.length; i += 1) {
console.log(arguments[i]);
}
---------------------------------------------------------------------
arguments.length 返回值: 3
---------------------------------------------------------------------
arguments对象遍历返回值:
1
2
3
由此可见,形参只是一个占位符罢了,实际参数以
arguments
对象为准
caller
属性:
- 属性值: 对象(当前函数调用者的引用)
- 顶层调用返回:
null
- 示例:
function f() {
console.log( f.caller );
}
f(); // null
function f1() {
f()
}
f1() // 返回 f1()函数的引用(体)
length
属性:
- 返回形参数量(整数)
- 默认参数,剩余参数不计算在内
- 示例:
function f(a,b, c=10, ...d) {}
console.log(f.length);
// 返回2, c=100,...d没有统计在内
name
属性:
- 返回:当前函数的名称字符串
- 匿名函数,ES5返回空, ES6正常返回函数引用
- 示例:
function f1(){}
let f2 = function () {}
console.log(f1.name); // f1
console.log(f2.name); // f2(ES6)
prototype
属性
-
原型属性是函数中最重要的属性之一
-
原型属性
prototype
对象2个属性: -
任何对象都会有这二个属性
+constructor
: 当前函数的引用
+__proto__
: Object -
prototype
: 指向原型对象的拥有者,即当前函数引用 -
__proto__
: 指向原型对象的原型:Object
所有对象归根对底都是内置函数:
Object()
的实例
function F() {}
console.log(F.prototype);
/* 结果:
constructor: ƒ F()
__proto__: Object
*/
// 等价于
F.prototype = {
constructor: F(),
__proto__: Object
}
- 如果这是一个构造函数,那么这个原型对象是复制到新的实例中
扩展知识:
- JavaScript是基于原型链继承的
- 每个实例都会从它的构造函数的原型对象上复制属性到自身
- 所以,不存在完全空白的对象(除非重写构造函数的原型对象)
constructor
属性:
- 返回当前函数的构造函数
- 函数也是对象,所有也有构造器
- 函数构造就是构造函数:
Function
- 示例:
function f() {}
console.log(f.constructor); // Function
- 为什么是构造函数:
Function
呢? - 因为所有函数都是
Function
的实例 - 即: 函数除了用关键字function创建外,还可以用它
Function(): 参数必须全部是字符串,最后一个是函数体,前都是形参
let sum = new Function('a', 'b', 'return a + b;')
console.log( sum(5, 3) ); // 8
// 与下面函数定义等价: 函数字面量
let sum1 = function (a, b) { return a + b; }
console.log( sum1(5, 3) ); // 8
toString()
方法
- 该方法是函数从它的构造函数原型上继承过来的方法
- 其实所有对象,都有这个方法,该方法来自:
Object()
- 该方法返回函数的字符串表示
function f(a,b) { return a + b; }
console.log(f.toString());
//"function f(a,b) { return a + b; }"
valueOf()
方法
- 该方法是函数从它的构造函数原型上继承过来的方法
- 其实所有对象,都有这个方法,该方法来自:
Object()
- 该方法返回函数的值,即函数声明
function f(a,b) { return a + b; }
console.log(f.valueOf());
//function f(a,b) { return a + b; }
// 与toString()相比,仅仅是去掉了一对双引号("...")定界符
apply()
和 call()
方法
-
apply()
与call()
用于自定义函数的调用者 - 二者第一个参数,都是调用函数的对象
-
call(obj, param...)
: 参数以列表方式传递 -
apply(obj, [param...])
: 参数以数组方式传递
function f1(a,b){return a + b;}
// 全局调用
f1(2,3);
// 全局对象是window,以下也是合法调用
window.f1(2,3); // 5
// this 当前指向全局对象window
this.f1(2,3); // 5
// call()可人为设置函数调用者,以下调用与上面等效
// 在window对象上调用 f1()
f1.call(window,3,5); // 8
// 在this指向的变量对象上调用 f1()
f1.call(this,3,5); // 8
// apply()功能与call()一样,仅参数传递方式不同
// call()列表传参, apply()数组传参
f1.apply(window,[3,5]); // 8
f1.apply(this,[3,5]); // 8
网友评论