js中this的情况

  1. 关于JS中THIS的处理情况汇总
    (1)给当前元素的某个事件行为绑定方法,当事件行为触发,方法被执行,方法中的this一般都是当前操作的元素。排除:IE6~8中,基于attachEvent进行的DOM2事件绑定,方法中的this是window
        document.body.onclick=function (){
            console.log(this);   //body
        };
        document.body.addEventListener('click',function(){
            console.log(this);  //body
        });

(2)函数执行,看函数前面是否有”点“,有”点“,”点“前面是谁this就是谁,没有"点”,this是window。JS严格模式下,没有“点”,this是undefined;匿名函数(自执行函数/回调函数)一般this是window/undefined;括号表达式中有特殊的处理。

        const fn=function (){
            consoel.log(this);
        };
        let obj={
            name:'obj',
            fn:fn
        };
        fn();  //window
        obj.fn();   //obj
        
        (obj.fn)();   //this->obj
        //括号表达式中有多项,也只取最后一项;但是this是window,而不是之前的obj
        (10,20,obj.fn)();   //this->window
        
        (function (){
            console.log(this);   //window
        })(); 
        
        [1,2].sort(function (a,b){
            console.log(this);  //window
        });
        
        [1].forEach(function (item,index){
        //forEach内部做了特殊的处理,传递的第二个参数是为了改变回调函数中的this指向的
            console.log(this);  //obj
        },obj);

(3)构造函数执行“new xxx",函数体中的this 是当前类的实例

        function Fn(){
            this.x=10;
        }
        Fn.prototype.sum=function (){};
        Fn();  //window
        let f=new Fn();   //this->f
        f.sum();   //this->f
        f.__proto__.sum();   //this->f.__proto__

(4)ES6中的箭头函数(或者基于{}形成的块级上下文)里面没有this,如果代码中遇到this也不是自己的,而是它所在上下文中的this.

        let obj={
            name:'obj',
            fn(){
                //this->obj
                //1s后执行函数,把obj.name改为lly
                let that=this;
                setTimeout(function(){
                    //that存储的是上级上下文中的this
                    that.name='lly';
                },1000);

            //简单的方法:使用箭头函数
                setTimeout(()=>{
                    //this->用的是上级上下文中的this,也就是obj.
                    this.name='lly';
                },1000);
            }
        };
        obj.fn();

(5)可以基于Function.prototype上的call/apply/bind方法强制改变函数中的this指向,对箭头函数没有效果,因为其不存在this.
call方法

    <script>
        const fn=function(x,y){
            this.total=x+y;
            console.log(this);
        }
        let obj={
            name:'lly'
        }
        fn();  //this->window
        obj.fn();  //报错:obj.fn is not a function 
        //call方法
        //函数.call([context],params1,params2,...)
        //简单:把函数执行,让函数中的this指向[context],并且把params1/params2...作为实参传递给函数
        //详细说明:
        //首先fn基于原型链__proto__,找到Function.prototype.call方法,并且把call方法执行
        //call方法中的this就是当前操作的实例fn,传递给call方法的第一个实参是未来改变fn中的this指向,剩余的实参,都是未来要依次传递给fn的参数信息
        //call方法执行的过程中,实现了这样的处理:把fn【call中的this】执行,让fn中的this指向[context],并且把params1,params2...作为实参传递给fn,以此达到最后的效果
        //最后接收fn执行的返回结果,作为返回值返给外部
        let res=fn.call(obj,10,20);
        fn.call(10,20);  //this->10 x=10  y=undefined
        fn.call(); //fn:this->window 第一个参数不传或者传递的是null/undefined,在JS非严格模式下,最后fn中的this都是window(严格模式下,不传this是undefined,传递null/undefined,this也会改为对应的值)
        
    </script>

apply方法
函数.apply([context],[params1,params2,…])
call和apply的唯一区别:执行函数的时候,需要传递给函数的参数信息,在最开始传递给call/apply的时候,形式不一样。
call是需要把参数一个个传递给call,call方法内部再一个个传递给函数
apply是需要把参数放在一个数组中传递给apply,但是apply内部也会帮我们把接受数组中的每一项一项项的传递给函数
fn.apply(obj,[10,20]);
bind方法
call/apply在执行的时候,都会立即把要操作的函数执行,并且改变它的this指向
bind是预处理:执行bind只是预先把函数中需要改变的this等信息存储起来(预设好),但是此时函数并不会被执行,执行bind会返回一个匿名函数,当后期执行匿名函数的时候,再去把之前需要执行的函数执行,并且改变this为预设的值。

需求:1s后执行,并且让fn中的this变为obj,传递10,20
setTimeout(fn,1000); //1s后执行fn,但是this->window,x/y都是undefined
setTimeout(fn.call(obj,10,20),1000); //这样也不可以,因为在设置定时器的时候,基于call方法,就把fn已经执行了,虽然this和参数都可,但是并不是在1s后执行的。把fn执行的返回结果绑定给定时器,1s后执行的是返回结果。
setTimeout(function(){ fn.call(obj,10,20) },1000); //这样可以
setTimeout(fn.bind(obj,10,20),1000); //可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值