函数的四种调用模式

参数this在面向对象编程中非常重要,它的值取决于 调用的模式。

前言:

函数一般分为四种调用模式:
1.函数调用模式: 一般独立函数调用
2.方法调用模式: 作为方法调用,一定要有一个引导对象(宿主对象)
3.构造器调用模式: 一定用来初始化对象,有 new 引导,return 可以重定向
4.上下文调用模式: apple 或 call 

函数调用模式

函数的定义方式

  1. 声明式
  2. 表达式式
  3. Function

单独独立调用的就是函数

函数名(参数);

函数调用模式中,this 表示 全局对象 window

方法调用模式

方法本身就是函数,但是方法不是单独独立的使用,而是通过对象引导调用

对象.方法( 参数 );

方法调用模式中, this 指向引导方法的对象

方法调用一定要有宿主对象

方法一定是 某个对象 的 方法。对象可以是任何对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function foo() {
console.log( this );
}
var o = { name : "Tom" };
o.foo = foo;
foo(); //函数调用
o.foo();//方法调用
--------------------------
function func () {
console.log(' 函数也是是对象 ');
}
func.foo = foo;
foo();//函数调用
func.foo();//方法调用

构造器调用模式(构造函数模式 或 构造方法模式)

  • constructor
  • 特征: 在函数前面用 new 来引导
  • this 的含义: 刚刚被创建出来的实例对象
  • 注意返回值
  • 调用构造函数时,无参可省略括号
  • 执行步骤
1
2
3
4
5
6
7
8
9
10
11
12
var p = new Person();
// new 是运算符,用来申请创建对象,创建出来的对象传递给构造函数的 this
//利用构造函数对其初始化
function Person () {
this.name = "Tom";
this.age = "19";
this.gender = "男";
}
// 返回值
// 如果不写return,那么构造函数 默认返回 this
// 若在构造函数中写return ,并紧跟基本类型(如 return num,ruturn 123).则忽略返回类型
// 若在构造函数中写return,并紧跟 引用类型 ,那么构造函数返回 该引用类型数据,忽略 this

构造函数小结

(1) 构造函数无参数,可以省略括号

1
var p = new Person;

(2) 创建对象并直接调用 其方法

1
2
3
4
5
( new Person () ).sayHello();
//可以省略调整结合性的括号
new Person ().sayHello();
//若省略构造函数的括号,就必须加结合性的括号
( new Person ).sayHello ();

上下文调用模式

  • 特征: 一定是由一个对象引导调用
  • this 的含义: 引导调用的这个对象

-> 上下文调用模式

-> 术语 上下文: 就是 this.

-> 上下文调用模式有标准的调用语法:
  函数名.call( ... )
  函数名.apply( ... )

-> 上下文调用模式这两个形式功能一模一样. 只是参数的形式不同.
-> 上下文调用之所以称为上下文调用, 是因为我们允许利用参数来改变 this 的含义.
1
2
3
4
5
6
7
8
9
10
11
例如:
var o1 = { name: 'jim' };
var o2 = { name: 'tom' };
function func() { console.log( this ); }
func() // 函数模式 => window
o1.func = func;
o1.func(); // 方法模式 => o1
func.call( o1 ); // this 就是 o1
func.call( o2 ); // this 就是 o2
func.call( null ); // this 就是 window
  说明:
    在利用上下文调用的时候, call 或 apply 的第 0 个参数表示就是 函数中 this 的指向
    如果传入 null 或 undefined 或不传, this 就是 window
    如果传入的是 对象, this 就是传入对象
    如果传入的是 基本类型( 数字, 字符串, boolean )就会将基本类型转换成对应包装类型, 赋值给 this
-> 关于参数
  call 在调用的时候, 函数的参数散列的在 call 中提供.
  apply 在调用的时候, 函数的参数以数组的形式提供.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
例如: ( 填空题 )
function func( num1,num2 ) {
console.log( num1 + num2 );
}
如果用 call 来调用, 下面的代码 与 func( 1, 2 ) 调用等价
func.call( null, 1, 2 )
如果用 apply 来调用, 下面的代码与 func( 3, 4 ) 调用等价
func.apply( null, [ 3, 4 ] )
验证:
看下面这个代码:
function func( arr, callback ) {
for ( var i = 0; i < arr.length; i++ ) {
callback( arr[ i ], i );
}
}
这个 func 用 call 和 apply 分别怎么调用
如果以函数的形式调用
func( 'a,b,c'.split( ',' ), function ( v, i ) {
console.log( i + ', ' + v );
} )
注意: 有了这个写法, 表示以前凡是使用 函数 与 方法的地方都可以修改成 上下文调用模式
例如:
var html = template( 'tpl', {} );
=> var html = template.call( null, 'tpl', {} );
var html = template.apply( null, [ 'tpl', {} ] );