之前一直对函数中this的指向问题是懵的,突然下定决心去搞懂,所以就小小的记录一下自己对this的理解呀,有不对的还请指出奥
一、在理解函数中this指向之前,我们先来搞懂函数的定义方式有哪些
1.函数表达式(匿名函数)
var fn = function () { }
2.函数声明方式
function fn1 () { }
3.new关键字方式定义函数
var fun2 = new Function()
使用new关键字也可以传参new Function(‘a’, ‘b’, ‘console.log(‘传参和函数体都必须要用引号包起来哦’)’)
二、理解函数如何调用,以及函数中的this指向
1.普通函数
function fn () {}
// 调用方式一
fn()
// 调用方式二
fn.call()
// 调用方式三
fn.apply()
普通函数中的this指向的是window对象
2.对象中的方法函数
var obj = {
study: function () {}
}
// 调用
obj.study()
对象方法中的this指向的是当前对象,这里就是obj
3.构造函数
function Fn(){}
// 调用
var cathy = new Fn()
构造函数中的this指向的是被New出来的那个对象,这里就是指向cathy
4.事件函数调用(通过点击事件源元素触发)
btn.onclick = function(){}
事件函数中的this指向的是触发事件的事件源元素,这里就是btn
5.定时器函数(在指定时间内自动调用)
setInterval(function(){}, 1000)
定时器函数中的this指向的window对象,因为完整写法就是window.setInterval(function(){}, 1000)
6.立即执行函数(立即被调用)
(function() {})()
立即执行函数中的this指向的window对象,因为完整写法就是window.(function() {})()
三、搞懂了函数的调用和this指向后,我们来看看如何改变this的指向
1.使用call()方法,它的作用既可以修改函数的this指向,也能调用立即调用函数,还可以实现继承
1)实现修改this指向,要指向谁,第一个参数就传谁,其余参数用逗号分割
var obj = {
name: 'cathy'
}
var fn = function (a, b) {
console.log(a + b)
}
fn.call(obj, 1, 2)
2)实现继承
function Father(name, sex, age) {
this.name = name
this.sex = sex
this.age = age
}
function Son(name, sex, age) {
// 继承父元素的属性, 第一个参数this为修改父类this,指向为Son的this
Father.call(this, name, sex, age)
}
var son = new Son('cathy', 18, 'girl')
2.使用apply()方法,它的作用既可以修改函数的this指向,也能调用立即调用函数,和call的区别为出第一个外,其余参数以数组形式传递
1)实现修改this指向,要指向谁,第一个参数就传谁,以数组形式传递
var obj = {
name: 'cathy'
}
function fnApply(a, b) {
console.log(a + b)
}
// 要指向谁 就写谁
fnApply.apply(obj, [1, 2])
2)用于求数组中的最大值
var arr = [1, 3, 5, 2, 8]
Math.max.apply(null, arr)
Math.max.apply(Math, arr)
说明:使用apply调用max方法,如果不修改this指向则第一个参数填写null,或者指向max方法的调用者Math,第二个参数为数组,所以就直接传递arr
3.使用bind()方法,它的作用可以修改函数的this指向,但不会立即调用函数,并且会返回一个新的函数,与原函数主体一样,出第一个参数外,其余参数以逗号形式分割
function fnABind(a, b) {
console.log('bind', this)
console.log(a + b)
}
// 要指向谁 就写谁
var f = fnApply.bind(obj, 1, 2)
f()
使用bind的情形:
比如点击一个按钮,点击之后禁用,3s后在重新激活,这是就可以使用bind
btn.onclick = function() {
this.disabled = true
1 是用箭头函数 this指向离它最近的函数
setTimeout(() => {
this.disabled = false
}, 3000)
2 使用新变量接受this
var that = this
setTimeout(function() {
that.disabled = false
}, 3000)
3 使用bind
setTimeout(function() {
this.disabled = false
}.bind(btn), 3000)
4 或者 这个this在定时器外面 在btn里面 所以是btn的this
setTimeout(function() {
this.disabled = false
}.bind(this), 3000)
}