js中this指向的五种情况以及call、apply、bind的重写

js中this指向的五种情况

  1. 给元素的某个事件行为绑定方法,事件触发时,函数执行,此时的this一般都指向当前的这个元素。
// 给某个元素添加事件,要兼容DOM0和DOM2
function emit(element,type,func){
    
     //当调用多次emit时,要进行多次判断
    if(element.addEventListener){
    
    
        element.addEventListener(type,func,false);
    }else if(element.attachEvent){
    
    
        element.attachEvent('on'+type,func);
    }else{
    
    
        element['on'+type]=func;
    }
}
//利用惰性思想和闭包的机制实现了对emit函数的优化
function emit(element,type,func){
    
    
    if(element.addEventListener){
    
    
        emit=function(element,type,func){
    
    
            element.addEventListener(type,func,false);
        };
    }else if(element.attachEvent){
    
    
        emit=function(element,type,func){
    
    
            element.attachEvent('on'+type,func);
        };
    }else{
    
    
        emit=function(element,type,func){
    
    
            element['on'+type]=func;
        };
    }
    emit(element,type,func);
}
  1. 作为普通函数执行时,如果前面有点,则this指向点前面的;没有点的话非严格模式下为window,严格模式下为undefined。
  2. 作为构造函数执行时,this一般指向当前类的实例。
  3. 作为箭头函数,由于箭头函数中没有自身this,箭头函数中的this一般都是箭头函数所在上下文中的this.箭头函数没有构造器,不能被new执行,也没有arguments实参集合,可以通过...args获取。
  4. 通过 call 、apply、bind改变this指向
    call和apply 改变this的同时,直接执行了函数,只是传入的参数形式不同;
    bind:改变this,但不是立即执行函数。预先传递和处理了一些内容。(柯里化思想)
~function anonymous(proto) {
    
    
    function bind(context = window, ...args) {
    
    
        return (...innerArgs) => {
    
    
            this.apply(context, args.concat(innerArgs));
        };
    }
    function call(context = window, ...args) {
    
    
        context === null ? context = window : null;
        let type = typeof context;
        if (type !== "object" && type !== "function" && type !== "symbol") {
    
    
            //基本类型
            switch (type) {
    
    
                case 'number':
                    context = new Number(context);
                    break;
                case 'boolean':
                    context = new Boolean(context);
                    break;
                case 'string':
                    context = new String(context);
                    break;
            }
        }
        context.$fn = this;
        let result = context.$fn(...args);
        return result;
    }
    function apply(context = window, args) {
    
    
        context === null ? context = window : null;
        let type = typeof context;
        if (type !== "object" && type !== "function" && type !== "symbol") {
    
    
            //基本类型
            switch (type) {
    
    
                case 'number':
                    context = new Number(context);
                    break;
                case 'boolean':
                    context = new Boolean(context);
                    break;
                case 'string':
                    context = new String(context);
                    break;
            }
        }
        context.$fn = this;
        let result = context.$fn(...args);
        return result;
    }
    proto.bind = bind;
    proto.call = call;
    proto.apply = apply;
}(Function.prototype)

猜你喜欢

转载自blog.csdn.net/weixin_42123213/article/details/106460709