自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

函數(shù)中的 this 不止有 72 變

開發(fā) 前端
在課程 連接你、我、他 —— this 中我們學習了 this,最后留了一個問題,如何修改 this 的指向,今天一起學習。

在課程 連接你、我、他 —— this 中我們學習了 this,最后留了一個問題,如何修改 this 的指向,今天一起學習。

修改 this 的指向可通過 apply、call、bind 這三個函數(shù)中的任意一個實現(xiàn)。那這三個函數(shù)是誰的方法呢?

在 MDN 中我查到了:

這張圖說明了這 3 個函數(shù)是 Function prototype 的方法,也就是說「每個函數(shù)都有著三個方法」。當定義一個函數(shù),這個函數(shù)默認包含這三個方法。

我們感受一下 Vue.js 中關(guān)于 apply、call 和 bind 的使用:

apply 的應(yīng)用:

  1. function once (fn) { 
  2.   var called = false
  3.   return function () { 
  4.     if (!called) { 
  5.       called = true
  6.       fn.apply(this, arguments); 
  7.     } 
  8.   } 

call 的應(yīng)用:

  1. var hasOwnProperty = Object.prototype.hasOwnProperty; 
  2. function hasOwn (obj, key) { 
  3.   return hasOwnProperty.call(obj, key) 

bind的應(yīng)用:

  1. function polyfillBind (fn, ctx) { 
  2.   function boundFn (a) { 
  3.     var l = arguments.length; 
  4.     return l 
  5.       ? l > 1 
  6.         ? fn.apply(ctx, arguments) 
  7.         : fn.call(ctx, a) 
  8.       : fn.call(ctx) 
  9.   } 
  10.  
  11.   boundFn._length = fn.length; 
  12.   return boundFn 
  13.  
  14. function nativeBind (fn, ctx) { 
  15.   return fn.bind(ctx) 
  16.  
  17. var bind = Function.prototype.bind 
  18.   ? nativeBind 
  19.   : polyfillBind; 

你可能看不懂上面的用法,下面我們一一拋開謎底。

當一個新事物的出現(xiàn),總是有目的的,那么 apply、call 和 bind 的出現(xiàn)是為了解決什么問題呢?它們?yōu)槭裁词呛瘮?shù)的方法呢?為什么不是其它對象的方法。

通過 apply、call 可以自定義 this 調(diào)用某個函數(shù),比如定義一個全局函數(shù)(嚴格模式):

  1. 'use strict'; 
  2. function gFun(name, age) { 
  3.     console.log(this); 

這個函數(shù)可以通過下面 5 種方式調(diào)用,也就是說通過 apply、call、bind 可以調(diào)用一個函數(shù) F,其中「函數(shù) F 執(zhí)行上下文中的 this 可以在調(diào)用時指定」:

1.直接調(diào)用:

  1. gFun('suyan', 20); // this 為 undefined 

2.通過 this 調(diào)用:

  1. this.gFun('suyan', 20); // this 為 window 

3.通過 apply 調(diào)用,把所有的參數(shù)組合成一個數(shù)組作為 apply 的參數(shù):

  1. gFun.apply(this, ['suyan', 20]); // this 為 window 

4.通過 call 調(diào)用,參數(shù)通過逗號分割,這是與 apply 調(diào)用的區(qū)別:

  1. gFun.call(this, 'suyan', 20);  // this 為 window 

5.通過 bind 調(diào)用,會返回一個原函數(shù)的拷貝,并擁有指定的 this和參數(shù):

  1. let bGFun = gFun.bind(this, 'suyan', 20); 
  2. bGFun();  // this 為 window 

我們一起看一些例子:

例1、setTimeOut 的使用:

  1. const time = { 
  2.     second: 1, 
  3.     afterOneSecond() { 
  4.         setTimeout(function () { 
  5.             this.second += 1; 
  6.             console.log(this.second); 
  7.         }, 1000); 
  8.     } 
  9. }; 
  10. time.afterOneSecond(); 

上面這段代碼執(zhí)行后,第 6 行代碼的打印結(jié)果是 NaN,在連接你、我、他 —— this 這節(jié)課程中我們有提到過 this 設(shè)計的一個弊端是不能繼承。其實可以通過 bind 改造一下這個函數(shù):

  1. const time = { 
  2.     second: 1, 
  3.     afterOneSecond() { 
  4.         setTimeout(this.timeInvoke.bind(this), 1000); 
  5.     }, 
  6.     timeInvoke() { 
  7.         this.second += 1; 
  8.         console.log(this.second); 
  9.     } 
  10. }; 
  11. time.afterOneSecond(); 

函數(shù) timeInvoke 通過 bind 綁定 this,并返回一個新的函數(shù),執(zhí)行結(jié)果為 2。bind 好像具有「暫存」的功能,把當前的 this 暫存起來。

例 2、函數(shù)調(diào)用

  1. const person = { 
  2.     name: 'suyan', 
  3.     age: 20, 
  4.     showName(pre) { 
  5.         return pre + '-' + this.name; 
  6.     }, 
  7.     update(name, age) { 
  8.         this.name = name; 
  9.         this.age = age; 
  10.     } 
  11. }; 
  12.  
  13. function generateName(fun) { 
  14.     let name = fun(); 
  15.     console.log('showName = ', name); 
  16.  
  17. generateName(person.showName); 

執(zhí)行上面代碼會報錯,因為 showName 中的 this 為 undefined:

可以通過 bind 「暫存 this」:

  1. const person = { 
  2.     name: 'suyan', 
  3.     age: 20, 
  4.     showName(pre) { 
  5.         return pre + '-' + this.name; 
  6.     }, 
  7.     update(name, age) { 
  8.         this.name = name; 
  9.         this.age = age; 
  10.     } 
  11. }; 
  12.  
  13. function generateName(fun) { 
  14.     let name = fun(); 
  15.     console.log('showName = ', name); 
  16. // 指定 this 為 person 對象 
  17. let bindShowName = person.showName.bind(person, '前端小課'); 
  18. generateName(bindShowName); 

例 3、構(gòu)造函數(shù),通過 call 來調(diào)用某個函數(shù),替換 this。

  1. function Product(name, price) { 
  2.     this.name = name; 
  3.     this.price = price; 
  4.  
  5. function Food(name, price) { 
  6.     // 調(diào)用 Product 函數(shù) 
  7.     Product.call(this, name, price); 
  8.     this.catagory = 'food'
  9. let food = new Food('包子', 1); 
  10. console.log(food.name); // 包子  

例 4、調(diào)用匿名函數(shù)

  1. const animals = [ 
  2.     { 
  3.         name: 'King' 
  4.     }, 
  5.     { 
  6.         name: 'Fail' 
  7.     } 
  8. ]; 
  9.  
  10. for (let i = 0; i < animals.length; i++) { 
  11.     (function (i) { 
  12.         // 可以直接使用 this 
  13.         this.print = function () { 
  14.             console.log('#' + i + ' ' + this.name); 
  15.         }; 
  16.         this.print(); 
  17.     }).call(animals[i], i); 

結(jié)果為:

回頭再看看課程開始之前 Vue 中關(guān)于 apply、call 和 bind 的應(yīng)用,是不是能看懂了?

 

責任編輯:趙寧寧 來源: 素燕
相關(guān)推薦

2010-08-24 10:12:45

2014-01-21 09:29:45

國產(chǎn)操作系統(tǒng)操作系統(tǒng)

2009-08-03 18:24:28

C# 4.0協(xié)變和逆變

2020-03-20 19:10:37

支付寶新版移動應(yīng)用

2010-04-23 19:54:16

2015-08-17 11:30:51

2018-04-17 12:28:33

iOS 11.4蘋果ClassKit

2010-09-09 11:17:44

SQL函數(shù)公歷

2010-04-23 15:40:26

72ub手機費

2011-01-14 10:27:18

C#.netasp.net

2020-06-23 15:00:45

AI人工智能遠程辦公

2021-04-16 15:17:19

Windows 10Windows操作系統(tǒng)

2015-09-10 04:42:10

iPone蘋果發(fā)布會

2015-02-02 10:03:50

2024-02-22 12:18:16

Python函數(shù)用法

2022-04-18 20:12:03

TypeScript靜態(tài)類型JavaScrip

2011-08-08 10:47:45

超微機箱服務(wù)器

2022-04-13 11:18:48

滲透測試Mock
點贊
收藏

51CTO技術(shù)棧公眾號