JavaScript之this

this 是什么

this即不是指向自身函数 也是不是指向函数的词法作用域
this是函数被调用的发生的绑定,指向什么取决与函数在哪里调用

this 的四种绑定规则

默认绑定

在非严格的模式下,默认绑定的this指向全局对象,严格模式下this指向undefined

//默认绑定
    //默认绑定的this指向全局对象
    function foo() {
        var a = 1;
        console.log(this === window);
        console.log(this.a);
    }
    var a = 2;
    foo(); //true  2
	// 严格模式this绑定到undefined
	function foo2() {
        "use strict"; 
        console.log(this.a); 
    }
    foo2();//Uncaught TypeError: Cannot read properties of undefined (reading 'a')

隐式绑定

函数在调用位置,是否有上下文对象,如果有则隐式绑定到这个对象上

 //隐式绑定
    //使用对象来调用其内部的方法,该方法的this是指向该对象本身
    var myObj = {
        a:"name",
        showName:function(){
            console.log(this.a)//name
            console.log(this);//{a: 'name', showName: ƒ} 
        }
    }
 myObj.showName();

显式绑定

通过apply call bind 将函数的this绑定到指定的对象上

 // 显式绑定
    // 改变函数执行时的this指向为myObj1
    var myObj1 = {
        a:"3", 
    }
    function foo1(){
        console.log(this.a);       
    }
    foo1() //2
    foo1.call(myObj1)//3

apply,call,bind三者的区别

fun.call(thisArg, param1, param2,…)call方法的第一个参数是this的指向,后面传入的是一个参数列表
fun.apply(thisArg,[param1,param2,…])和call基本上一致,唯一区别在于传参方式
fun.bind(thisArg, param1,param2, …)语法和call一模一样,区别在于立即执行还是等待执行

  1. 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。
  2. 三者都可以传参,但是apply是数组,而call是参数列表
  3. bind 是返回绑定this之后的函数,便于稍后调用;apply 、call则是立即执行
 //call、apply和bind异同
    var myObj2 = {
        name:"name",
        myage:"10",
        myFun(x,y){
            console.log(this.name,this.age,x,y); 
        }
    }
    myObj2.myFun() //name undefined
    var myObj3 = {
        name:"aaa",
        age:"10"
    }
    //区别
    myObj2.myFun.call(myObj3,33,44) //aaa 10 33 44
    myObj2.myFun.apply(myObj3,[55,66]) //aaa 10 55 66
    myObj2.myFun.bind(myObj3,77,88)() //aaa 10 77 88

应用

  //1 call应用   
    function Father(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    function Son(name){
        //借用父类的方法:修改它的this指向,赋值父类的构造函数里面方法、属性到子类上
        Father.call(this,name)
    }
    var son = new Son("小明");
    console.log(son.name);//小明
    console.log(son.colors);//['red', 'blue', 'green']
    //判断原生引用类型
    console.log(Object.prototype.toString.call([1,2,3]));//[object Array]
    console.log(Object.prototype.toString.call(123));    //[object Number]
    //2 apply应用
    var arr = [15, 6, 12, 13, 16];
    console.log(Math.max(15, 6, 12, 13, 16)); //16
    console.log(Math.max.apply(Math,arr));   //16
    //3 bind应用
   /*  for(var i =0;i<=5;i++){
        setTimeout(function(){
            console.log(i);  //6个6      
        },i*1000)
    }*/
    for(var i =0;i<=5;i++){
        setTimeout(function(i){
            console.log(i);  //0 1 2 3 4 5     
        }.bind(this,i),i*1000)
    } 

new绑定

通过构造函数中设置,使用构造调用的时候,this会自动绑定在new 期间创建的对象上

 // new绑定
    function Foo(name) {
        this.name = name;
    }
    var a = new Foo("aaa");
    console.log(a.name);//"aaa"
    //1 创建一个全新的对象
    //2 给新对象的内部属性赋值,构造原型链
    //3 这个新对象会绑定到函数调用的this
    //4 如果函数没有返回其他对象,那么会自动返回这个新对象

箭头函数

箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this

 //箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this。
    var c= "c"
    let o = {
        c : "ccc",
        func: function () {
            let showName = () => { 
                console.log(this)   //{c: 'ccc', func: ƒ} 
                console.log(this.c) //ccc  
            }; 
            showName();
        }
    };
    o.func()

参考
1https://juejin.cn/post/6844903630592540686#heading-1
2 https://juejin.cn/post/6844904009308831751#heading-10
3 《你不知道的JavaScript》第二章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值