???????????????????????????????????????????????????????????????????????????????ó?????
?????e????????????????????ɡ?????????????????????????????
????(function() {
????// ??????????
????var raw_fn = Element.prototype.setAttribute;
????...
????})();
???????????????????????????????
?????????????????????
????raw_fn.apply(this?? arguments)
?????????????????????????????? Function.prototype.apply ??????????????????????????????????????????
??????????????????????????????????????д apply??????????????? setAttribute ?£?????????????????????? raw_fn ???
????Function.prototype.apply = function() {
????console.log('????????????????:'?? this);
????};
????document.body.setAttribute('a'?? 1);
????Run

????????????????????????????????????????????????????
????????????? Function.prototype.apply ?????????????????????????????????????? apply.apply.apply.apply...
?????????apply ?? call ?????????????? call ??????
??????????????????????? apply ?? call ?????????????????? this ??????????????????£?????Щ??????????? this ???
????obj.method()
????method.call(obj)
????ò?????????????????????????????÷?????????????????д?????е??????????????????????
????????????????????????????????????????????

 

(function() {
// ??????????
Element.prototype.__setAttribute = Element.prototype.setAttribute;
// ?????????
Element.prototype.setAttribute = function(name?? value) {
// ?????????? ...
// ???????
this.__setAttribute(name?? value);
};
})();
Run

??????????????? apply ?????????????????????__setAttribute??????????????????????????????????????ó??????????????????????????????????λ??????????

 

(function() {
// ?????????????
var token = '$' + Math.random();
// ??????????
Element.prototype[token] = Element.prototype.setAttribute;
// ?????????
Element.prototype.setAttribute = function(name?? value) {
// ?????????? ...
// ???????
this[token](name?? value);
};
})();
Run

????????????????????????????????????????? this[token](...) ???????????????????????о???????÷???
?????????????????????????????о????????????????????????????????????????????????? Element.prototype ?????£??????????????????????????

 

for(var k in Element.prototype) {
console.log(k);
if (k.substr(0??1) == '$') {
console.error('¥?????????????????????????????');
console.error(Element.prototype[k]);
}
}
Run


????????????????????????????е????棬????????????????????????????????ε?????????????????e??????????????????????滻???
???????????????????????????????????????????????????α???????? —— ??????????????????
??????????????
??????????????????? JavaScript ????????????? enumerable??configurable ?????????????????????????????????????????????
?????????????
????// ??~ ???????????
????Object.defineProperty(Element.prototype?? token?? {
????value: Element.prototype.setAttribute??
????enumerable: false
????});
????Run
???????棬????????????????????????????????
??????????????й???????????????????
???????????????????и????????? apply ????????????????????????????Щ????????? test ??????????????Сд?????????? forEach ????????????????д???
??????????? RegExp.prototype.test ??д?????????????? false??????????????ж?????Ч???
????????????????????????裬????Щ????????????????????????????????????
???????? call ?? apply
????????????????????????????????????? Geek ????????ú????????
????????????????????????????????????????????????????Object.defineProperty ???к????????????????????????????????????д???????????
?????????????????д??????????????? Function.prototype.call ?? apply ???????????????????????????д???????

 

Object.defineProperty(Function.prototype?? 'call'?? {
value: Function.prototype.call??
writable: false??
configurable: false??
enumerable: true
});
// apply ????
???????Ч????
Function.prototype.call = function() {
alert('hello');
};
console.log(Function.prototype.call);
???????
function call() { [native code] }
Run

?????????????????????? call ?? apply????????ù???????????????
???????????????+???????????????????????????????????????????????????????????????а??????
????????????????????????????