javascript - 常见的五种this指向

Javacript中this的使用

this 在js中是一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。简单的来说,this就是函数运行时所在的环境对象。今天我们来看一下常见的this的四种使用…

函数调用

  • 严格模式下不允许this指向全局变量
  • 非严格模式下this就是指向全局变量
1
2
3
4
5
6
7
8
// 严格模式下‘use strict’
function thisFun(){
console.log(this)
}
thisFun() // undefined

// 非严格模式下
thisFun(); // window

对象的方法调用

  • 调用对象的方法,this指向方法的调用者
  • 将对象的方法赋值给另一个变量,this指向该变量所在的对象上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var userName = 'cindy'
var userInfo = {
userName:'pis',
getUserName:function(){
console.log(this.userName)
}
}
userInfo.getUserName(); // pis
var otherUser = userInfo.getUserName;
otherUser();// window cindy

var me = {
userName:'eric',
realName:''
}
me.realName = userInfo.getUserName;
me.realName() // me eric

构造函数

在js中,为了实现类,定义了构造函数,在调用构造函数生成实例的时候,使用new操作符

1
2
3
4
5
var name = 123;
function Animal(){
this.name = 'cat';
}
var mimi= new Animal(); // this指向构造函数生成的实例对象

call apply bind

  • apply、call、bind的作用

在javascript中,三者作用是改变某个函数的执行上下文(Execution Context),具体作用是改变函数体内部this的指向。

举个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    function example() {}
example.prototype = {
name: 'will',
say: function() {
console.log('hi,' + this.name + '!')
}
}
var e = new example()
e.say() // hi,will!


var obj = {
name: 'lucky'
}
e.say.apply(obj) // hi,lucky! 此时this.name是lucky
e.say.call(obj) // hi,lucky! 此时this.name是lucky
e.say.bind(obj)() // hi,lucky! 此时this.name是lucky
  • apply、call、bind的区别

apply、call只是接受参数的方式不太一样,而且会立即执行,bind会产生一个新函数,需要再次调用才会执行

举个栗子:

1
2
3
4
5
function func(arg1, arg2) {
console.log(arg1 + arg2)
}
func.apply(this, [1, 2]) // apply接受的参数,第一个是对象,第二个是数组
func.call(this, 1, 2) // call接受的参数,第一个是对象,后面一个接一个
  • 简单举几个apply、call、bind的应用场景

伪数组转标准数组

1
2
3
4
5
6
7
var obj = {
0: 1,
1: 2,
length: 2
}
var arr1 = Array.prototype.slice.call(obj) // [1, 2]
var arr2 = Array.prototype.slice.apply(obj) // [1, 2]

取数组中的最大值或者最小值

1
2
3
4
5
6
7
8
9
var arr = [1, 2, 3, 4]
//取最大值
console.log(Math.max.apply(Math, arr)) // 4
console.log(Math.max.call(Math, ...arr)) // 4


//取最小值
console.log(Math.min.apply(Math, arr)) // 1
console.log(Math.min.call(Math, ...arr)) // 1

检验是否是数组

1
2
3
4
5
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]'
}
isArray([1]) // true
isArray({}) // false

React中使用bind使函数可以获取到props

1
2
3
4
5
6
7
8
9
10
    class MyCircle extends Component {
constructor(props) {
super(props)
this.func = this.func.bind(this)
}
func() {
...
}
...
}

等等…

总结

三者作用都是改变函数this的指向
三者第一个传参都是要this要指向的对象
apply、call是立即执行函数,bind需要再次调用

初到贵宝地,有钱的给个钱场,没钱的挤一挤给个钱场