使用:javascript
// 1. 定义一个女孩叫x var x = { // 她的身高是170 height: 170, // 她有一双高跟鞋,做用是让她长高10厘米 highShoes: function(){ this.height += 10 } } // x穿上高跟鞋 x.highShoes() // 因而身高变成了180 console.log(x.height) // 180 // 2. 定义一个帅哥叫q var q = { // 他的身高是160,... height: 160 } // q也想增高一下 // q.highShoes() // 可是报错了:Uncaught TypeError: q.highShoes is not a function // 由于q没有高跟鞋 // 3. q借用x的高跟鞋 x.highShoes.call(q) // 我也长高啦! console.log(q.height) // 170 // 这里的this就是指高跟鞋的拥有者,即x女孩 // 若是不经过call改变this的指向,这个高跟鞋的拥有者永远是x // q经过call借来了x的高跟鞋
因此,call的做用就是:java
高跟鞋搬运工git
改变this的指向github
apply, bind的做用同上。数组
和call的区别:闭包
// 定义一个主人翁 var x = {} // 定义一个化妆函数 function makeUp(color, style) { // 涂什么颜色的口红 this.lips = color // 留什么样式的发型 this.hair = style } // 用call: makeUp.call(x, 'red', 'longHair') // 用apply: makeUp.apply(x, ['red', 'longHair']) // 用bind: makeUp.bind(x, 'red', 'longHair')()
第一个参数为null时:app
makeUp.call(null, 'yellow', 'shortHair') // 非严格模式下,第一个参数是null,this指向的window console.log(window.lips, window.hair) // "yellow", "shortHair"
实现一个call函数:函数
/* * call的工做原理就是 * 将一个函数的this指向某个上下文,从而使这个上下文能够调用这个函数。 * * 函数就像某个工具, * call要完成的就是一个借用的过程。 * * 一曲《借我》送给你们。 */ Function.prototype.lendMe = function (borrower) { // 1. 谁借?默认是window借。 var borrower = borrower || window // 2. 借啥?哪一个函数调用的lendMe,lendMe的this就是这个函数。 // 当把这个函数赋值给borrower的方法时,就已经借到了。 borrower.tool = this // 得到传给函数的参数 var args = [...arguments].slice(1) // 3. 借用。前面是借,如今是用。 var result = borrower.tool(...args) // 4. 出来借老是要还的。 delete borrower.tool // 5. 用完的东西给你。 return result }
apply和call几乎同样:工具
Function.prototype.myApply = function (borrower) { var borrower = borrower || window borrower.tool = this // 第二个参数是一个数组 var arg = arguments[1] || [] var result = borrower.tool(...arg) delete borrower.tool return result }
实现一个bind函数:this
/* * 这里对bind函数的实现, * 就是利用闭包,返回了一个准备经过apply的方式执行的函数。 */ Function.prototype.myBind = function (borrower) { if(typeof this !== 'function'){ throw new TypeError('Error') } var tool = this var args = [...arguments].slice(1) return function() { return tool.apply(borrower, args.concat(...arguments)) } }
JavaScript自我实现系列 点击查看