日常代码随笔
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
【不定期更新中】