JavaScript中this关键字和call(),apply(),bind()

发布于 2022-02-06  7 次阅读


首先明确一个概念,即:谁调用这个函数或者方法,this就指向谁。

通常来讲,this的调用分为以下几种情况:

1、全局this

全局的this就是指window对象。

console.log(this == window)
// 输出:true

2、函数中的this

函数中的this原则上是谁调用函数,函数中的this就指向谁,一般情况下,函数都是挂在window对象上的,即函数中的this也指向window对象。

但是,如果开启了严格模式“use strict”,那么函数中的this将不会指向window对象。

function myfun(){ return this }
console.log(myfun() === window.myfun())
// 输出:true

3、对象方法中的this

this关键字会指向对象本身。

var myobj = {
    item: '1',
    printItem: function() {
        return this.item;
    }
}
console.log(myobj.printItem())
// 输出:1

4、构造函数中的this

构造函数中的this指向的是new操作符创建出来的实例。

function myClass(item, content) {
    this.item = item;
    this.content = content;
    this.showThis = function() {
        console.log(this)
    }
}
var myC1 = new myClass(1, 'content')
myC1.showThis()
// 输出:myClass {item: 1, content: 'content', showThis: ƒ}

5、借来的this

所有的函数都拥有三个方法,可以修改函数中this的指向。

1)call:主动的将函数中的this指向新对象,调用立即执行。

var obj = {
  name: "li",
  myfun: function (a, b) {
    console.log(this.name + `, ${a}, ${b}`);
  },
};
var newobj = { name: "wang" };

obj.myfun.call(newobj, 'a', 'b');
// 输出:wang, a, b

2)apply:效果同apply,语法稍有区别。

obj.myfun.apply(newobj, ['a', 'b']);
// 输出:wang, a, b

3)bind:被动式的改变this的指向。

const newMyfun = obj.myfun.bind(newobj);
newMyfun('new a', 'new b')
// 输出:wang, new a, new b

4)call,apply,bind的总结

相同点:(1)都属于“函数对象”上的方法;

(2)第一个参数都是绑定作用域,修改this的指向;

(3)都可以传递参数

不同点:(1)apply,call兼容性更好,适合即刻调用;

(2)bind出自ES5,某些低版本浏览器不支持,一般用在修改回调函数的作用域;

(3)apply传递的参数必须是用数组进行包装,而call和bind则是将要传递的参数一一列出。

6、ES6箭头函数中的this

因为箭头函数没有this,在箭头函数内调用的this始终指向外部,同时也不能使用call,apply,bind等方法来改变this的指向。

es6obj = () => {
    console.log(this)
}
es6obj()
// 输出:Window {0: Window, 1: Window, window: Window, self: Window, document: document, name: '', location: Location, …}