This详解

this指向

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

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

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

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

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

2.函数中的this 

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

3.定时器中的this

 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>

 

  • 对象中的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. 第一个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,验证结果正确
    
  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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值