使用: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自我實現系列 點擊查看