日常代码随笔

1,this指向问题的代码:

var _getElementById = document.getElementById;
document.getElementById =  function(id){
    console.log(1);
    return _getElementById(id);
    
}
var button = document.getElementById( 'button' );
//Uncaught TypeError: Illegal invocation
    at HTMLDocument.document.getElementById (<anonymous>:5:12)
    at <anonymous>:8:23

异常发生在_getElementById(id)这句,此为一个全局函数,调用全局函数时候this指向是window,而document.getElementById内部实现this指向是document。所以需要在调用时候将this指向document对象。改动后代码如下:

document.getElementById =  function(){
    console.log(1);
    return _getElementById.apply(document,arguments);  //此处document可用this代替
    
}
var button = document.getElementById( 'button' );

那其实除了上面的方法,还可以直接传递document.getElementById函数进去,进行重写该方法,使用了闭包,保证函数作用域中this指向执行调用它的函数,嗯,优秀:

document.getElementById = (function(fn){
   return function(){
       return fn.apply(this,arguments);
   }
}(document.getElementById))

2,例1中代码其实可以用装饰者模式实现:

Function.prototype.before = function(beforefn){
    var _self = this;
    return function(){
        beforefn.apply(this,arguments);  //this指向beforefn
        return _self.apply(this,arguments);
    }
}
document.getElementById = document.getElementById.before(function(){
      console.log(1)
})
var button = document.getElementById( 'button' );

 3,call和apply的妙用

var arr = [1,2,4,5];
Math.max.apply(null,arr)  //5

//寻找数组中第一次出现b字符串的地方
var arr = ['aaacc','ff','abc'];
"".indexOf.call(arr,'b');  //10,貌似逗号也算进去了

var arr = ['aaabc'];
console.log(''.indexOf.call(arr,'b')); //3

 【不定期更新中】

原文地址:https://www.cnblogs.com/tangjiao/p/10107383.html