版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
函数的四种调用模式
注意:在函数声明的时候是无法确定this的指向,只有当函数调用的时候才能确定下来!
在函数中this的指向是灵活的,要想知道this的指向需要分析两点:
- 看this是属于哪个函数的
- 看函数是何种调用模式
根据函数内部this的指向不同,可以将函数的调用模式分成4种
- 函数调用模式
- 构造函数调用模式
- 方法调用模式
- 上下文调用模式(借用方法模式)
什么是函数?什么是方法?
函数:当一个函数不是一个对象的属性时,我们称之为函数。
方法:当一个函数被保存为对象的一个属性时,我们称之为方法。
一、函数调用模式
定义:如果一个函数不是一个对象的属性时,就是被当做一个函数来进行调用的。此时this指向了window。
//函数调用模式
function fn(){
console.log(this);//window
}
//函数名(),这种函数调用模式属于函数调用模式,this指向的是window
fn();
二、构造函数调用模式
function Person(){
console.log(this);//Person {}
}
// new 构造函数() 这种调用模式属于构造函数调用模式
// 构造函数内的this指向了新创建的实例对象。
var p = new Person();
三、方法调用模式
var obj = {
sayHi:function(){
console.log(this);//obj
}
}
//在方法调用模式中,this指向调用当前方法的对象。
obj.sayHi();//点语法调用
obj["sayHi"]();//中括号语法调用
四、上下文调用模式
上下文调用模式也叫方法借用模式
戳这里详细了解call,apply,bind
作用:
apply方法和call方法作用一样
- 可以来调用模式
- 来修改函数内的this指向(第一个参数)
- 其他参数可以给函数传递实参
var xm = {
name: '小明',
age: 10,
fn: function (a, b) {
console.log(this.age); // undefined
console.log(a + b); //NaN 非数值
}
}
var fn2 = xm.fn;
//若不传参,和函数调用模式相同,this指向window
fn2.call();
var xm = {
name: '小明',
age: 10,
fn: function (a, b) {
console.log(this.age); // 10
console.log(a + b); //30
}
}
var fn2 = xm.fn;
//修改了this指向,此时指向了xm这个对象
//fn2.apply(xm,[10,20]);
fn2.call(xm,10,20);
3.bind()
bind()方法创建一个新的函数, 可以绑定新的函数的this指向
var fn = function () {
console.log(this);//window
}
fn(); //函数调用模式,this指向window
//fn和fn2长的一样,但是在内存中是两份函数,地址是不一样。
var fn = function () {
console.log(this);//[10, 20, 30]
}
var fn2 = fn.bind( [10, 20, 30] ); // fn2 是创建的新函数,新函数和fn长的一样。
console.log(fn === fn2); // false
//fn和fn2长的一样,但是在内存中是两份函数,地址是不一样。
fn2();
//fn2函数是由bind创建出来的, fn2函数内的this指向被固定了,所以this指向了[10, 20, 30]
//固定的理解: 不论fn2 函数的调用模式是何种,fn2内的this指向被固定写死了。
最后:说几种特殊的this指向
- 定时器中的this指向了window,因为定时器的function最终是由window来调用的。
戳这里了解三种修改定时器this指向的方法 - 事件中的this指向的是当前的元素,在事件触发的时候,浏览器让当前元素调用了function。