js中this指向详细总结

关于js中this的指向的总结

1.概述

首先要知道,函数中this的指向在函数定义时是决定不了的,只有在函数执行时才能决定指向谁,实际上this始终指向调用这个函数的对象

2.函数中this指向的三种情况

(1)当函数中有this,但是函数没有被上一级对象调用时

当函数没有被对象调用的时候,函数中的this指向的是默认对象window(注意:严格模式中默认对象不是Window而是undefined)

就相当于是被window调用的。所以此时函数中的this指向的就是window。

function f() {
            let a = "hello";
            console.log(this.a);//undefined
            console.log(this);//window
        }
        f();
(2)当函数中有this,并且被上一级对象调用时

当函数被上一级对象调用时,此时函数中的this指向的就是调用该函数的对象。

let one = {
            a: "hello",
            fn: function() {
                console.log(this.a);//hello
            }
        }
        one.fn();
(3)当函数中有this,且函数中包含多个对象时

此时尽管这个函数是被最外层对象调用的,但是this依旧只是指向函数的上一级对象

let one = {
            a: "hello",
            b: {
                a: "world",
                fn: function() {
                    console.log(this.a); //world
                    console.log(this); //{a: "world", fn: ƒ}
                }
            }
        }
        one.b.fn();
(4)有个特殊的例子需要注意以下
let one = {
            a: "hello",
            b: {
                a: "world",
                fn: function() {
                    console.log(this.a); //undefined
                    console.log(this); //Window
                }
            }
        }
        let j = one.b.fn;
        j();

这里可能会比较迷惑,为什么这里的this又指向了window呢?其实道理也很简单,因为这里只是把one.b.fn的值赋值给了j,并没有调用函数。下面执行到 j() 才调用了函数,而此时没有任何对象调用 j 。现在我们回忆一下之前说的第一种情况,不难想到此时的this指向的应该是window。

3.new 会改变this的指向

function f() {
            this.a = "hello";
            console.log(this); //f {a: "hello"}
        }

        let b = new f();
        console.log(b.a); //hello

为什么b可以点出f里的a呢,这是因为new关键字可以改变函数中this的指向,将函数的this指向修改为函数的实例化对象。

4.当函数内有this,且该函数有return时

(1)返回值为引用类型的this指向
function f() {
            this.a = "hello";
            return a{};
        }
        let b = new f();
        console.log(b.a); //undefined

这里为什么又发生了变化?因为当函数返回值为引用类型时,函数中的this会指向它返回的那个对象,也就是这里的{}。那么如果返回值是基本类型会怎么样呢?

(2)返回值为基本类型的this指向
function f() {
            this.a = "hello";
            return 1;
        }
        let b = new f();
        console.log(b.a); //hello
function f() {
            this.a = "hello";
            return "world";
        }
        let b = new f();
        console.log(b.a); //hello

可以看到,当返回值是基本类型时,结果和原来是一样的,因此当函数返回值时一个基本类型时,函数中的this指向的时函数的实例化对象。

特例:

function f() {
            this.a = "hello";
            return null;
        }
        let b = new f();
        console.log(b.a); //hello

虽然null是对象,但是他的结果和基本类型的是一致的。

5.call、apply、bind可以改变函数内this指向

(1)call(this指向的对象,传递参数,参数....)

call可以将函数内的this指向传入的第一个参数,并且call会直接调用该函数,所以call多用于对象的继承。

let o = {
            name: 'ldh'
        }

        function fn(age) {
            this.age = age;
            console.log(this);
        }
        fn(18); //window
        fn.call(o, 18); //o
        console.log(o.age); //18
(2)apply(this指向的对象,数组)

apply和call很相似,都可以改变函数内this的指向并且都会直接调用该函数(调用apply的函数fn:fn.apply(o,[1,2,3])),不同的地方就在于apply必须要用数组传递参数但call不需要,所以apply经常用于跟数组有关系的操作. 比如借助于数学对象实现数组最大值最小值。

let o = {
            name: 'ldh'
        }
function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        fn(1, 2); //window 3
        fn.apply(o, [1, 2]); //o 3
        //借助于数学对象实现数组最大值
        let m = Math.max.apply(Math, [1, 56, 12, 74]);
        console.log(m);//74
(3)bind(绑定的对象,参数,参数...)

bind也可以改变函数内this指向,但是与call、apply不同的是bind不会直接调用函数,因此想不调用函数,但是还能改变this指向就应该用bind, 比如改变定时器内部的this指向.

let o = {
            name: 'ldh'
        }
        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        let f = fn.bind(o, 1, 2);
        f();//o 3
posted @ 2021-07-21 10:12  律动之心  阅读(622)  评论(0)    收藏  举报