搞清楚 this 的指向问题

不同环境下 functionthis 的不同指向

  1. 事件调用环境 - 谁触发事件,函数里面的 this 就指向谁
// css
#div1,
#div2 {
    width: 100px;
    height: 100px;
    background: #abcdef;
}
// html
// js const div1 = document.getElementById('div1') const div2 = document.getElementById('div2') function click() { this.style.background = 'red' } div1.onclick = click; div2.onclick = click;
  1. 全局环境
    a. 浏览器环境 - window
    b. node 环境 - module.exports
// a
console.log(this); // window
// b
console.log(this === module.exports); // true
  1. 函数内部
    a. this 最终指向的是调用它的对象
// 非严格模式下指向 window
function test() {
  console.log(this)
}
test(); // 实际上是 window.test() 
// 严格模式下指向 undefined
"use strict";
function test() {
    console.log(this)
}
test();
var obj = {
    a: 10,
    fn: function () {
        console.log(this)
    }
}
obj.fn(); // obj

b. 函数被多层对象所包含,如果函数被最外层对象调用,this 指向的也只是它上一级对象

var obj = {
    a: 10,
    fn: function () {
        console.log(this)
    },
    fn2: {
        fn3: function () {
            console.log(this)
        }
    }
}
window.obj.fn(); // obj
window.obj.fn2.fn3(); // fn2
var fn2 = obj.fn2; 
fn2.fn3(); // fn2
var fn3 = obj.fn2.fn3; 
fn3(); // window

c. 构造函数中的 this 指向的是实例对象

function fn() {
    this.num = 1;
}
fn.num = 2;
fn.prototype.num = 3;
fn.prototype.getNum = function () {
    console.log(this.num);
}
var prototype = fn.prototype;
var getNum = prototype.getNum;

new fn().getNum(); // 1
prototype.getNum(); // 3
getNum(); // undefined

注:new 一个构造函数的时候发生了什么?
1. 调用函数
2. 自动创建一个对象
3. 将创建出来的对象和 this 进行绑定
4. 如果构造函数返回的结果是一个对象,就返回这个对象;如果构造函数返回的不是一个对象,就返回创建的新对象。

d. 如果构造函数中有 return,且 return 值是一个对象,this 指向返回的对象,如果不是对象或者为 null,则保持原来规则(没有 return 时,隐式返回 this)

function fn1() {
    this.number = 1;
}
var obj1 = new fn1();
console.log(obj1.number); // 1

function fn2() {
    this.number = 2;
    return null
}
var obj2 = new fn2();
console.log(obj2.number); // 2

function fn3() {
    this.number = 3;
    return {
        number: 4
    }
}
var obj3 = new fn3();
console.log(obj3.number); // 4

function fn4() {
    this.number = 4;
    return []
}
var obj4 = new fn4();
console.log(obj4.number); // undefined
  1. 箭头函数 - 箭头函数本身是没有 thisarguments 的,在箭头函数中引用 this,实际上调用的是定义时的上一层作用域的 this。(注意:对象是不能形成独立作用域的)
var obj = {
    fn1: function () {
        console.log(this, 'fn1');
    },
    fn2: () => {
        console.log(this, 'fn2');
    }
}

obj.fn1(); // obj
obj.fn2(); // window

修改 this 指向的方法

callapply 的用法及异同详见:深入理解 call() 和 apply()
bind: 只是修改 this 指向,但不会执行,实际上返回了一个 function

你可能感兴趣的:(搞清楚 this 的指向问题)