利用函數執行,能夠造成一個"不銷燬的私有做用域的原理", 把須要預先處理的內容都存儲在這個不銷燬的私有做用域中 而且返回一個小函數,之後咱們執行的時候,執行的都是小函數 在小函數中,把以前預先存儲的值進行相關的操做便可
var obj = {name:'我對象呢'} function fn(num1,num2) { console.log(this,num1+num2); } window.setTimeout(fn.call(obj),0);
此處 fn.call(obj)沒有返回值,因此至關於數組
window.setTimeout(undefined,0)//並不會有輸出
能夠作以下修改瀏覽器
window.setTimeout(fn.bind(obj),0);// 輸出obj
此處的bind就是利用了柯里化思想,將fn中的this"預處理"成了windowapp
關於call 和 bind的區別,此處略去.bind在ie678下不兼容 Function.prototype.bind的原理:就是執行這個方法的時候,返回一個匿名函數 而後在匿名函數中把須要處理的函數以及this進行初始化函數
function myBind(callback,context){ // 咱們模擬bind方法,讓callback中的上下文變成咱們傳入的context context = context || window; // 獲取給小函數傳入的參數值 -> 這些參數值是除去callback和context以外的傳參 var outAry = Array.prototype.slice.call(arguments,1); // 返回一個待執行的匿名函數 return function(){ // 咱們的目的是經過bind返回一個函數 // 這個函數中的this已經被修改 // 函數不會被當即執行 //callback.call(context); callback.apply(context,outAry);//由於傳入參數是一個類數組,因此從call改成apply } }
對於元素的事件綁定:若是使用了bind方法,預先處理了this,那麼bind方法會把瀏覽器傳遞的事件對象放在當前函數的最後一個參數中this
div1.onclick = fn.bind(obj,100,200);// -> 輸出:obj, MouseEvent undefined
至關於 ->prototype
//這是js中bind的原理,它默認把事件e傳遞給了fn的最後一個參數 div1.onclick = function(e){ fn.call(obj,100,200,e); }
咱們重寫一下,把myBind方法寫在Function的原型上code
Function.prototype.myBind = function(context){ var _this = this; var outerAry = Array.prototype.slice.call(arguments,1); return function(){ var innerAry = Array.prototype.slice.call(arguments,0); _this.apply(context,outAry.concat(innerAry)); } }