函数的四种调用模式实际上就是在讨论一个函数中 this 的指向问题.
1. 分类
函数调用模式
方法调用模式
构造器调用模式
上下文调用模式
bind 模式
2. 函数调用模式
分辨: 函数调用没有任何引导数据, 就只有一个函数名来调用.
在函数调用模式中 this 表示 全局对象( 在浏览器中 就是 window );
function foo() { console.log( this ); } //函数调用 window foo ();
3. 方法调用模式
分辨: 方法调用模式一定要有一个对象, 是对象引导方法来调用的.
在方法模式中 this 表示引导对象( 当前对象 )
//方法调用 //this指的是object var o = { name: 'jim' }; o.func = foo; o.func();
4. 构造器调用模式
分辨: 方法在调用的时候 前面有一个 new 关键字引导.
在方法中 this 的含义就是刚刚被创建出来的 对象
a.构造函数的执行过程原理
使用 new 创建对象
构造函数调用, 将刚刚创建的对象引用传入到构造函数中的 this 中
因此 this 就是当前刚刚创建出来的对象
利用 对象的 动态特性来给对象增加成员
在调用 new 的时候, new 后面所跟的函数是什么, 创建出来的对象就继承什么的原型.
b 构造函数中的 return
1> 在构造函数中 使用 return 可以结束构造函数的执行. 直接将当前的 this 直接返回.
2> 如果 return 后跟是一个基本数据类型( 值类型 )或空类型, 这个数据无效, return 起作用.
3> 如果 return 后跟的是一个引用类型( 对象 ), 那么调用构造函数就会返回该数据. 创建出来的对象就会被 "丢弃"
//构造器调用模式 var length = 10; function fn(){ console.log(this.length); } var o = { length:5, method:function(f){ f(); arguments[0](); } } o.method(fn,1);
5.上下文调用模式
允许调用者控制函数中 this 的含义, 那么这样的调用就是上下文调用.
上下文, 就是环境, 依托的对象.
divElem.getElementsByName( 'div' )
上下文就是 this
上下文调用有两个方法可用
1> apply
如果函数调用需要提供参数, apply 方法的第一个参数用于指定 函数中 this 的含义.
如果第一个参数传入的是 null 或 undefined, 那么 this 就是 window.
如果第一个参数传入的是 基本数据类型( 值类型 ), 那么会将值类型转换成对应的包装类型, this 指向包装对象
如果第一个参数传入的是 对象, 那么 this 就是这个对象.
apply 方法的第二个参数是一个数组, 里面包含需要传给函数的所有参数
2> call
如果函数调用需要提供参数, call 方法的第一个参数用于指定 函数中 this 的含义.
如果第一个参数传入的是 null 或 undefined, 那么 this 就是 window.
如果第一个参数传入的是 基本数据类型( 值类型 ), 那么会将值类型转换成对应的包装类型, this 指向包装对象
如果第一个参数传入的是 对象, 那么 this 就是这个对象.
call 方法的第二个参数, 以及其他参数分别表示需要传入函数的各个参数
共同点: 两个方法都是在指定函数中 this 是指向什么对象.
// 上下文调用 两种方法apply call function method( message, a,b,c,d,e,f,g ) { console.log( arguments ); console.log( message + ', ' + this.name ); } var o1 = { name: '张三' }; method.apply( o1, [ '消息', 1,2,3,4,5,6,7,8,9,0 ] ); method.call( o1, '消息', 1, 2, 3, 4, 5, 6, 7 );
js 是一个弱类型的语言, 而是表示数据不是严格的要求数据类型
6.bind 模式
如果说使用 apply 或 call 是在调用的时候指定 this 的含义, 那么 bind 就是在调用之前指定 this 的含义.
提前绑定. 语法
函数.bind( 对象 ) -> 函数
// bind调用 var tmpFn = document.getElementsByTagName; var get = tmpFn.bind( document ); // 返回的还是函数 var dv = get( 'div' )[ 0 ]; // 已经隐含了一个条件, 就是说 get 函数中的 this 就是被绑定的对象 即 document dv.style.border = '1px dashed green'; dv.style.width = '100px'; dv.style.height = '50px';