# this指向

this指向问题一般情况下this的最终指向的是那个调用它的对象

# 1.全局作用域或者普通函数中this

指向全局对象window(注意定时器里面的this指向window)

    <script>
        // this指向问题一般情况下this的最终指向的是那个调用它的对象

        // 1.全局作用域或者普通函数中this指向全局对象window(注意定时器甲面的this指向window)
        console.log(this); //window
    </script>
1
2
3
4
5
6

# 2.函数中的this

img

**注:**匿名函数中的this也同样指向windows

# 3.定时器中的this

img

# 4.对象或者构造函数中的this

    <script>     
        // 2.调用中谁调用this指向谁
        var o = {
            sayHi: function() {
                console.log(this); // this指向的是o这个对象
            }
        }
        o.sayHi();
        // 3.构造函数中this指向构造函数的实例
        function fun(name, age) {
            this.name = name;
            this.age = age;
            console.log(this); //指向fun实例对象
        }
        var fun = new fun();
    </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • 对象中的this指向它本身
  • 构造函数中的this指向它这个构造函数

构造函数中的this因为new的过程使得this指向发生了转移

new的整个过程:

  1. new会在内存中创建一个新的空对像
  2. new会让this指向这个新对象
  3. 执行构造函数中的代码
  4. return这个新对象

# 5.绑定事件中的this

谁绑定事件this就指向谁

img

# 6.箭头函数this指向 特殊性

箭头函数的this指向它的父作用域,箭头函数声明在全局作用域下其this指向window,若不在全局作用域下,this指向其父作用域

箭头函数的this永远指向其父作用域,箭头函数没有自己的this

# 普通函数

img

# 箭头函数

img

# 改变this指向方法

# 1.call()方法 常用于继承

call(无数个参数);

  • 第一个参数:改变this指向
  • 第二个参数:实参
  • 使用之后会自动执行该函数,不适合用在定时器处理函数或者事件处理函数

img

# 2.apply()方法

apply(两个参数)

  • 第一个参数:改变this指向
  • 第二个参数:数组或者伪数组(里面为实参)
  • 特点:使用时候会自动执行函数,不适合用在定时器处理函数或者事件处理函数

img

# 3.bind()方法

bind(无数个参数)

  • 第一个参数:改变this指向
  • 第二个参数之后:实参
  • 返回值为一个新的函数
  • 使用的时候需要手动调用下返回的新函数(不会自动执行)
  • 作用:改变事件处理函数或者定时器处理函数的this指向

img

# 三者区别

call、applybind区别:前两个可以自动执行,bind不会自动执行,需要手动调用

call、bindapply区别:前两个都有无数个参数,apply只有两个参数,而且第二个参数为**[数组]**

# 经典例题🥳

# 原型和this

    function Fn() {
        this.x = 100;
        this.y = 200;
        this.getX = function() {
            console.log(this.x);
        }
    }
    Fn.prototype.getX = function() {
        console.log(this.x);
    };
    Fn.prototype.getY = function() {
        console.log(this.y);
    };

    var f1 = new Fn();
    var f2 = new Fn();
    console.log(f1.getX === f2.getX); //false  两个对象不能全等
    console.log(f1.getY === f2.getY); //true	 使用的一个构造函数,原型上的方法相同
    console.log(f1.__proto__.getY === Fn.prototype.getY); //true	对象的原型方法和构造函数的原型方法相同(指向同一个构造函数)
    console.log(f1.__proto__.getX === f2.getX); //false	对象原型的方法和对象的方法不相等
    console.log(f1.__proto__.getX === Fn.prototype.getX); //true	对象的原型方法和构造函数的原型方法相同(指向同一个构造函数)
    console.log(f1.constructor); //f  Fn()  构造函数对象的构造方法是FN()
    console.log(Fn.prototype.__proto__.constructor); //空函数	构造函数的原型的构造方法是空函数
    f1.getX(); //	100	
    f1.__proto__.getX(); //undefined	  原型上的方法没有给x赋值
    f2.getY(); //	200  
    Fn.prototype.getY(); //	undefined	  原型上的方法没有给x赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

解析:

  1. 第一个false,首先要想到的是 简单数据类型的比较是对值的比较,他们都是存在在栈空间,所以两个值可以相等。而复杂数据类型的比较大不相同,他们在栈空间存放的是地址,当比较两者时,比较的是地址,所以当两个就算是属性相同方法相同的对象比较时,他们的存放地址不同,所以不同。

  2. true的原因调用的是同一个原型上的方法,所以相同。

  3. true,f1.__proto__·指向的是Fn原型,再调用getY方法,这其实就等同于Fn.prototype.getY直接调用方法

  4. false,跟第一个同理,f1.__proto__.getX是原型上的方法,其存放地址与实例化对象f2.getX所指向的对象存放地址不相同。并非值的比较。

  5. true,f1.__proto__.getX === Fn.prototype.getX可以看作Fn.prototype.getX === Fn.prototype.getX两者相同,都是原型上的方法,地址也相同。

  6. 实例化对象的constructor指向的是Person,死记。

    // 构造函数Person
    function Person(name, age) {
        this.age = age;
        this.name = name;
        this.say = function() {
            console.log("我叫", this.name);
        }
    }
    // 验证:实例对象p的constructor属性指向构造函数Person
    var p = new Person("张三", 18);
    console.log(p.constructor === Person); //true,验证结果正确
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  7. ƒ Object() { [native code] } Fn.prototype指向的是Fn的原型。Fn原型对象的__proto__指向的是Object对象原型。而Object对象原型的constructor指向的是Object对象,可以参考下图:image-20220702174347263New2

  8. 100,f1是一个对象,它调用它自身的getX方法,此时的this只想他自己,所以输出100

  9. undefined,f1.__proto__指向的是fn原型,首先原型上本身就没有x,y属性值。其次调用的方法中的this指向调用它的对象

  10. f2调用原型上的方法,谁调用,this就只想谁。所以输出200

  11. 跟第9个一样,原型调用自身的方法,this指向自己,没有y值,所以是underfined

Last Updated: 2/23/2023, 9:05:22 AM