日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
函數(shù)中的 this 不止有 72 變

在課程 連接你、我、他 —— this 中我們學(xué)習(xí)了 this,最后留了一個(gè)問(wèn)題,如何修改 this 的指向,今天一起學(xué)習(xí)。

創(chuàng)新互聯(lián)公司是一家專業(yè)提供雙陽(yáng)企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、H5頁(yè)面制作、小程序制作等業(yè)務(wù)。10年已為雙陽(yáng)眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進(jìn)行中。

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

在 MDN 中我查到了:

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

我們感受一下 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; 

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

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

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

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

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

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

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

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

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

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

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

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

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

5.通過(guò) bind 調(diào)用,會(huì)返回一個(gè)原函數(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é)課程中我們有提到過(guò) this 設(shè)計(jì)的一個(gè)弊端是不能繼承。其實(shí)可以通過(guò) bind 改造一下這個(gè)函數(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 通過(guò) bind 綁定 this,并返回一個(gè)新的函數(shù),執(zhí)行結(jié)果為 2。bind 好像具有「暫存」的功能,把當(dāng)前的 this 暫存起來(lái)。

例 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í)行上面代碼會(huì)報(bào)錯(cuò),因?yàn)?showName 中的 this 為 undefined:

可以通過(guò) 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 對(duì)象 
  17. let bindShowName = person.showName.bind(person, '前端小課'); 
  18. generateName(bindShowName); 

例 3、構(gòu)造函數(shù),通過(guò) call 來(lái)調(diào)用某個(gè)函數(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é)果為:

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


分享題目:函數(shù)中的 this 不止有 72 變
地址分享:http://m.5511xx.com/article/dhiiode.html