柯里化思想:就是预处理机制
利用函数执行,可以形成一个"不销毁的私有作用域的原理",把需要预先处理的内容都存储在这个不销毁的私有作用域中并且返回一个小函数,以后我们执行的时候,执行的都是小函数在小函数中,把之前预先存储的值进行相关的操作即可
- bind()
- var预处理
- 给元素绑定某个方法的时候,当该方法执行的时候,浏览器会自动给当前的方法传递一个参数值--事件对象.同时,该方法中的this是元素本身
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"预处理"成了window
关于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方法会把浏览器传递的事件对象放在当前函数的最后一个参数中
div1.onclick = fn.bind(obj,100,200);// -> 输出:obj, MouseEvent undefined
相当于 ->
//这是js中bind的原理,它默认把事件e传递给了fn的最后一个参数div1.onclick = function(e){ fn.call(obj,100,200,e);}
我们重写一下,把myBind方法写在Function的原型上
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)); }}