//<button>获取随机的人</button> //<input type="text"> var user = { data:[ {name:"张三", age:37}, {name:"李四", age:43} ], clickHandler:function (event) { var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // 随机获取 0 或者 1 // 从数组中取出值,赋值到 Input 文本框内 $ ("input").val (this.data[randomNum].name + " " + this.data[randomNum].age); } } // 绑定事件 $ ("button").click (user.clickHandler);
当点击的时候,会报错,由于 clickHandler 方法中的 this 指向的是 button 元素。javascript
为了解决这个问题,咱们可使用 bind 方法。
使用以下代码:java
$ ("button").click (user.clickHandler.bind (user));
代替以前:数组
$ ("button").click (user.clickHandler);
可是,在 IE9 如下和 Firefox 3.x 的浏览器中,是不支持 Bind 方法的,因此能够考虑加入以下方法。浏览器
// 判断是否支持 Bind 方法 if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { throw new TypeError (" Function.prototype.bind - 绑定错误"); } var aArgs = Array.prototype.slice.call (arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { return fToBind.apply (this instanceof fNOP && oThis ? this : oThis, aArgs.concat (Array.prototype.slice.call (arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP (); return fBound; }; }
咱们继续咱们的例子,考虑以下代码:app
// 全局变量 var data = [ {name:"王五", age:12}, {name:"陈六", age:14} ] var user = { // 局部变量 data:[ {name:"张三", age:37}, {name:"李四", age:43} ], showData:function (event) { var randomNum = ((Math.random () * 2 | 0) + 1) - 1; console.log (this.data[randomNum].name + " " + this.data[randomNum].age); } } var showDataVar = user.showData; showDataVar (); // 王五 12 (这里说明是从 全局变量而不是局部变量中取数据)
当执行 showDataVar() 时,this 指向的是全局变量,而不是局部变量。这是由于 showDataVar() 是做为全局函数执行的,它是绑定的是全局做用域,也就是浏览器的 window 对象。dom
一样,咱们能够经过使用 bind 方法指定 this 的值来解决这个问题:函数
// 把 showData 绑定到 user 对象 var showDataVar = user.showData.bind (user); // 如今咱们获得了 user 的值 showDataVar (); // 张三 43
咱们知道在 JavaScript 中咱们能够传递函数,返回函数和借调函数。Bind() 方法会使借调函数变地很是简单易用。
以下代码:this
// 这里有个 cars 对象,它里面没有任何函数。 var cars = { data:[ {name:"黎明", age:14}, {name:"刘德华", age:2} ] } // 咱们能够从上面例子中借调 user 对象中 showData () 函数。 // 咱们绑定 user.showData 函数处理 cars 对象。 cars.showData = user.showData.bind (cars); cars.showData (); // 黎明 14
这样写的代码有个问题,就是会在 cars 对象中,新加一个函数(showData),这可能不是咱们的本意,由于可能 cars 对象中此前已经有了一个叫 showData 的属性或者函数了。咱们不想意外覆盖它。在下文中会说明,最好的借调方式是使用 Apply 或者 Call。url
柯里化:是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,而且返回接受余下的参数且返回结果的新函数的技术。百度百科的定义prototype
首先,看如下代码,是个有三个参数的方法 greet():
function greet (gender, age, name) { // 若是性别为男,使用 "先生", 不然使用 "女士"。 var salutation = gender === "male" ? "先生" : "女士"; if (age > 25) { return "你好," + name + salutation + "。"; } else { return "你好," + name + "。"; } }
接下来,咱们使用 bind() 来进行函数柯里化()。
// 由于咱们不想使用 this 关键字,因此第一个参数咱们传递 null。 var greetAnAdultMale = greet.bind (null, "male", 45); greetAnAdultMale ("李连杰"); // "你好,李连杰先生。" var greetAYoungster = greet.bind (null, "", 16); greetAYoungster ("成龙"); // "你好, 成龙。" greetAYoungster ("李小龙"); // "你好,李小龙。"
当咱们使用 bind() 进行柯里化的时候,除了最后一个外,全部的参数都被预设置好了。