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

淺析 JavaScript 中的方法鏈

開發(fā) 前端
方法鏈?zhǔn)且环N流行的編程方法,可以幫助你寫出更簡(jiǎn)潔易讀的代碼。在本文中我們一起學(xué)習(xí) JavaScript 中的方法鏈?zhǔn)鞘裁矗约八窃鯓庸ぷ鞯?。另外我們還會(huì)探討如何使用方法鏈接來提高代碼的質(zhì)量和可讀性。

 方法鏈?zhǔn)且环N流行的編程方法,可以幫助你寫出更簡(jiǎn)潔易讀的代碼。在本文中我們一起學(xué)習(xí) JavaScript 中的方法鏈?zhǔn)鞘裁矗约八窃鯓庸ぷ鞯?。另外我們還會(huì)探討如何使用方法鏈接來提高代碼的質(zhì)量和可讀性。

[[381301]]

JavaScript 中方法鏈

你一定曾經(jīng)用過 jQuery 之類的庫(kù),可能看到過類似的東西。在進(jìn)行級(jí)聯(lián)時(shí)主要有兩種方法:一種是一個(gè)接一個(gè)的執(zhí)行方法,另一種是在同一行上。在純 JavaScript 中這種做法也很普遍。你可以在數(shù)組、字符串和 promise 看到它。

在這些情況下所有的過程都是相同的。首先引用要使用的對(duì)象。然后根據(jù)需要使用多種方法。但不是單獨(dú)使用這些方法,而要一個(gè)接一個(gè)地使用?;旧鲜前阉鼈冩溄釉谝黄稹O瓤匆恍├?。

方法鏈的例子

在處理字符串時(shí)有兩種方法。第一個(gè)種不用方法鏈,這要求必須在字符串上分別使用每個(gè)方法,這樣必須每次都引用這個(gè)字符串。

第二種方式是用方法鏈。這時(shí)可以用所有想要的字符串方法。寫出的代碼也可以是單行或多行,這取決于你的習(xí)慣。而且只需要引用一次字符串。盡管結(jié)果相同,但是代碼量卻有很大的差異。

 

  1. // 在字符串上使用方法鏈的例子 
  2. let myStr = ' - Hello-world. ' 
  3.  
  4. // 不用方法鏈: 
  5. myStr = myStr.toLowerCase() 
  6. myStr = myStr.replace(/-/g, ' '
  7. myStr = myStr.trim() 
  8.  
  9. // 用方法鏈: 
  10. myStr = myStr.toLowerCase().replace(/-/g, ' ').trim() 
  11.  
  12. // 多行方法鏈的寫法: 
  13. myStr = myStr 
  14.   .toLowerCase() 
  15.   .replace(/-/g, ' '
  16.   .trim() 
  17.  
  18. // 查看 "myStr" 的值 
  19. console.log(myStr) 
  20. // Output
  21. // 'hello world.' 

在數(shù)組上也能用方法鏈:

 

  1. // 在數(shù)組上使用方法鏈的例子 
  2. let myArray = [1, 7, 3, null, 8, null, 0, null'20', 15] 
  3.  
  4. // 不用方法鏈: 
  5. myArray = myArray.filter(el => typeof el === 'number' && isFinite(el)) 
  6. myArray = myArray.sort((x, y) => x - y) 
  7.  
  8. // 使用方法鏈: 
  9. myArray = myArray.filter(el => typeof el === 'number' && isFinite(el)).sort((x, y) => x - y) 
  10.  
  11. // 多行方法鏈的寫法: 
  12. myArray = myArray 
  13.   .filter(el => typeof el === 'number' && isFinite(el)) 
  14.   .sort((x, y) => x - y) 
  15.  
  16. // 查看 "myArray" 的值. 
  17. console.log(myArray) 
  18. // Output
  19. // [ 0, 1, 3, 7, 8 ] 

Promise 是一個(gè)很好的例子,因?yàn)樵谑褂脮r(shí)差不多全都是方法鏈。首先創(chuàng)建一個(gè) promise,然后添加適當(dāng)?shù)奶幚砗瘮?shù)。

 

  1. // 創(chuàng)建 Promise 
  2. const myPromise = new Promise((resolve, reject) => { 
  3.   // 創(chuàng)建一個(gè)假延遲 
  4.   setTimeout(function() { 
  5.     // 用一條簡(jiǎn)單的消息解決諾言 promise 
  6.     resolve('Sorry, no data.'
  7.   }, 1000) 
  8. }) 
  9.  
  10. // 使用方法鏈: 
  11. myPromise.then((data) => console.log(data)).catch(err => console.log(error)) 
  12.  
  13. // 多行方法鏈的寫法: 
  14. myPromise 
  15.   .then((data) => console.log(data)) 
  16.   .catch(err => console.log(error)) 
  17. // Output
  18. // 'Sorry, no data.' 

方法鏈?zhǔn)窃鯓庸ぷ鞯?/h3>

接下來研究它是怎樣工作的。答案很簡(jiǎn)單,是因?yàn)?this 。

假設(shè)有一個(gè)對(duì)象。如果在該對(duì)象內(nèi)使用 this,它會(huì)引用這個(gè)對(duì)象。如果創(chuàng)建該對(duì)象的實(shí)例或副本,則 this 將會(huì)引用這個(gè)實(shí)例或副本。當(dāng)你使用某些字符串或數(shù)組方法時(shí),實(shí)際上是在用一個(gè)對(duì)象。

 

  1. const myObj = { 
  2.   name'Stuart'
  3.   age: 65, 
  4.   sayHi() { 
  5.     // 這里的 this 是 myObj 的引用 
  6.     return `Hi my name is ${this.name}.` 
  7.   }, 
  8.   logMe() { 
  9.     console.log(this) 
  10.   } 
  11.  
  12. myObj.sayHi() 
  13. // Output
  14. // 'Hi my name is Stuart.' 
  15.  
  16. myObj.logMe() 
  17. // Output
  18. // { 
  19. //   name'Stuart'
  20. //   age: 65, 
  21. //   sayHi: ƒ, 
  22. //   logMe: ƒ 
  23. // } 

如果是字符串,則使用的是原始數(shù)據(jù)類型。但是你所使用的方法例如 toLowerCase(),存在于 String 對(duì)象的原型中。在對(duì)象上使用方法鏈還有一個(gè)關(guān)鍵要素:this。

為了使鏈起作用,方法必須返回與其一起使用的對(duì)象,也就是必須返回 this。就像接力賽跑時(shí)的接力棒一樣。

在 JavaScript 中實(shí)現(xiàn)方法鏈

為了使方法鏈有效,必須滿足三個(gè)條件:首先,需要一些對(duì)象。其次,該對(duì)象需要一些以后可以調(diào)用的方法。第三,這些方法必須返回對(duì)象本身,它們必須返回 this 才能使用方法鏈。

讓我們創(chuàng)建一個(gè)簡(jiǎn)單的對(duì)象 person。person 有 name, age 和 state 屬性。state 用來表示當(dāng)前處于什么狀態(tài)。要想改變這個(gè)狀態(tài),需要用到幾個(gè)方法:walk(), sleep(), eat(), drink(), work() 和 exercise()。

由于我們希望所有這些方法都是可鏈的,所以它們都必須返回 this。另外代碼中還有一個(gè)用來把當(dāng)前狀態(tài)記錄到控制臺(tái)的工具方法。

 

  1. // 創(chuàng)建 person 對(duì)象 
  2. const person = { 
  3.   name'Jack Doer'
  4.   age: 41, 
  5.   state: null
  6.   logState() { 
  7.     console.log(this.state) 
  8.   }, 
  9.   drink() { 
  10.     // 修改 person 的 state. 
  11.     this.state = 'Drinking.' 
  12.  
  13.     // 把狀態(tài)輸出到控制臺(tái) 
  14.     this.logState() 
  15.  
  16.     // 返回 this 值。 
  17.     return this 
  18.   }, 
  19.   eat() { 
  20.     this.state = 'Eating.' 
  21.     this.logState() 
  22.     return this 
  23.   }, 
  24.   exercise() { 
  25.     this.state = 'Exercising.' 
  26.     this.logState() 
  27.     return this 
  28.   }, 
  29.   sleep() { 
  30.     this.state = 'Sleeping.' 
  31.     this.logState() 
  32.     return this 
  33.   }, 
  34.   walk() { 
  35.     this.state = 'Walking.' 
  36.     this.logState() 
  37.     return this 
  38.   }, 
  39.   work() { 
  40.     this.state = 'Working.' 
  41.     this.logState() 
  42.     return this 
  43.   } 
  44.  
  45. //  
  46. person 
  47.   .drink() // Output'Drinking.' 
  48.   .exercise() // Output'Exercising.' 
  49.   .eat() // Output'Eating.' 
  50.   .work() // Output'Working.' 
  51.   .walk() // Output'Walking.' 
  52.   .sleep() // Output'Sleeping.' 
  53.  
  54. // 寫在一行上 
  55. person.drink().exercise().eat().work().walk().sleep() 
  56. // Output
  57. // 'Drinking.' 
  58. // 'Exercising.' 
  59. // 'Eating.' 
  60. // 'Working.' 
  61. // 'Walking.' 
  62. // 'Sleeping.' 

方法、鏈、this 和箭頭函數(shù)必須使用

也意味著無(wú)法使用箭頭函數(shù)創(chuàng)建方法鏈。因?yàn)樵诩^函數(shù)中,this 沒有綁定到對(duì)象的實(shí)例,而是全局對(duì)象 window 的引用。如果返回 this,那么返回的不是對(duì)象本身而是 window。

另一個(gè)問題是從箭頭函數(shù)內(nèi)部訪問和修改對(duì)象屬性。由于 this 是全局對(duì)象 window,所以不能用它來引用對(duì)象及其屬性。

如果你一定要使用箭頭函數(shù),必須想辦法繞過這種方法。不用 this 來引用該對(duì)象,必須直接通過其名稱引用該對(duì)象,也就是用對(duì)象名替換所有出現(xiàn)在箭頭功能內(nèi)的 this。

 

  1. // 創(chuàng)建 person 對(duì)象 
  2. const person = { 
  3.   name'Jack Doer'
  4.   age: 41, 
  5.   state: null
  6.   logState() { 
  7.     console.log(this.state) 
  8.   }, 
  9.   drink: () => { 
  10.     person.state = 'Drinking.' 
  11.  
  12.     person.logState() 
  13.  
  14.     return person 
  15.   }, 
  16.   eat: () => { 
  17.     person.state = 'Eating.' 
  18.  
  19.     person.logState() 
  20.  
  21.     return person 
  22.   }, 
  23.   exercise: () => { 
  24.     person.state = 'Exercising.' 
  25.  
  26.     person.logState() 
  27.  
  28.     return person 
  29.   }, 
  30.   sleep: () => { 
  31.     person.state = 'Sleeping.' 
  32.  
  33.     person.logState() 
  34.  
  35.     return person 
  36.   }, 
  37.   walk: () => { 
  38.     person.state = 'Walking.' 
  39.  
  40.     person.logState() 
  41.  
  42.     return person 
  43.   }, 
  44.   work: () => { 
  45.     person.state = 'Working.' 
  46.  
  47.     person.logState() 
  48.  
  49.     return person 
  50.   } 
  51.  
  52. //  
  53. person 
  54.   .drink() // Output'Drinking.' 
  55.   .exercise() // Output'Exercising.' 
  56.   .eat() // Output'Eating.' 
  57.   .work() // Output'Working.' 
  58.   .walk() // Output'Walking.' 
  59.   .sleep() // Output'Sleeping.' 

這樣做的缺點(diǎn)是靈活性不好。如果如果用Object.assign() 和 Object.create()復(fù)制對(duì)象,所有箭頭函數(shù)仍然會(huì)硬連接到原始對(duì)象。

 

  1. // 創(chuàng)建原始 person 對(duì)象 
  2. const person = { 
  3.   name'Jack Doer'
  4.   age: 41, 
  5.   state: null
  6.   logState() { 
  7.     // 打印整個(gè)對(duì)象 
  8.     console.log(this) 
  9.   }, 
  10.   drink: () => { 
  11.     person.state = 'Drinking.' 
  12.  
  13.     person.logState() 
  14.  
  15.     return person 
  16.   }, 
  17.   eat: () => { 
  18.     person.state = 'Eating.' 
  19.  
  20.     person.logState() 
  21.  
  22.     return person 
  23.   } 
  24.  
  25. // 讓 person eat 
  26. person.eat() 
  27. // Output
  28. // { 
  29. //   name'Jack Doer'
  30. //   age: 41, 
  31. //   state: 'Eating.'
  32. //   logState: ƒ, 
  33. //   drink: ƒ, 
  34. //   eat: ƒ 
  35. // } 
  36.  
  37. // 基于person對(duì)象創(chuàng)建新對(duì)象。 
  38. const newPerson = new Object(person) 
  39.  
  40. // 修改 "name" 和 "age" 屬性 
  41. newPerson.name = 'Jackie Holmes' 
  42. newPerson.age = 33 
  43.  
  44. // 讓 newPerson drink。 
  45. // 這會(huì)打印 Jack Doer 而不是 Jackie Holmes。 
  46. newPerson.drink() 
  47. // Output
  48. // { 
  49. //   name'Jack Doer'
  50. //   age: 41, 
  51. //   state: 'Drinking.'
  52. //   logState: ƒ, 
  53. //   drink: ƒ, 
  54. //   eat: ƒ 
  55. // } 

但是,如果用 Object() 構(gòu)造函數(shù),就不會(huì)發(fā)生上述問題。如果用 new 關(guān)鍵字的和 Object() 構(gòu)造造函數(shù),將會(huì)創(chuàng)建獨(dú)立的新對(duì)象。當(dāng)你對(duì)這個(gè)新對(duì)象使用某個(gè)方法時(shí),它將僅對(duì)這個(gè)新對(duì)象有效,而對(duì)原始對(duì)象無(wú)效。

 

  1. // 創(chuàng)建原始 person 對(duì)象 
  2. const person = { 
  3.   name'Jack Doer'
  4.   age: 41, 
  5.   state: null
  6.   logState() { 
  7.     // 打印整個(gè)對(duì)象 
  8.     console.log(this) 
  9.   }, 
  10.   drink: () => { 
  11.     person.state = 'Drinking.' 
  12.  
  13.     person.logState() 
  14.  
  15.     return person 
  16.   }, 
  17.   eat: () => { 
  18.     person.state = 'Eating.' 
  19.  
  20.     person.logState() 
  21.  
  22.     return person 
  23.   } 
  24.  
  25. // 讓 person eat. 
  26. person.eat() 
  27. // Output
  28. // { 
  29. //   name'Jack Doer'
  30. //   age: 41, 
  31. //   state: 'Eating.'
  32. //   logState: ƒ, 
  33. //   drink: ƒ, 
  34. //   eat: ƒ 
  35. // } 
  36.  
  37. // 基于 person 對(duì)象創(chuàng)建新對(duì)象  
  38. const newPerson = new Object(person) 
  39.  
  40. // 修改 "name" 和 "age" 屬性 
  41. newPerson.name = 'Jackie Holmes' 
  42. newPerson.age = 33 
  43.  
  44. // 讓 newPerson drink. 
  45. newPerson.drink() 
  46. // Output
  47. // { 
  48. //   name'Jackie Holmes'
  49. //   age: 33, 
  50. //   state: 'Drinking.'
  51. //   logState: ƒ, 
  52. //   drink: ƒ, 
  53. //   eat: ƒ 
  54. // } 

如果你一定要用箭頭功能,并想要復(fù)制對(duì)象的話,最好用 Object() 構(gòu)造函數(shù)和 new 關(guān)鍵字創(chuàng)建這些副本。否則只需要用常規(guī)函數(shù)就夠了。

方法鏈和類

如果你喜歡使用 JavaScript 類,也可以在JavaScript中使用方法鏈接。除了語(yǔ)法略又不同外,整個(gè)過程和對(duì)象是一樣的。但是要注意所有可鏈的方法都必須返回 this。

 

  1. // 創(chuàng)建 Person 類 
  2. class Person { 
  3.   constructor(name, age) { 
  4.     this.name = name 
  5.     this.age = age 
  6.     this.state = null 
  7.   } 
  8.  
  9.   logState() { 
  10.     console.log(this.state) 
  11.   } 
  12.  
  13.   drink() { 
  14.     this.state = 'Drinking.' 
  15.  
  16.     this.logState() 
  17.  
  18.     return this 
  19.   } 
  20.  
  21.   eat() { 
  22.     this.state = 'Eating.' 
  23.  
  24.     this.logState() 
  25.  
  26.     return this 
  27.   } 
  28.  
  29.   sleep() { 
  30.     this.state = 'Sleeping.' 
  31.  
  32.     this.logState() 
  33.  
  34.     return this 
  35.   } 
  36.  
  37. // 創(chuàng)建 Person 類的實(shí)例 
  38. const joe = new Person('Joe', 55) 
  39.  
  40. // 使用方法鏈 
  41. joe 
  42.   .drink() // Output'Drinking.' 
  43.   .eat() // Output'Eating.' 
  44.   .sleep() // Output'Sleeping.' 

總結(jié)

方法鏈?zhǔn)欠浅S杏玫模梢詭湍憔帉懜?、更易讀的代碼。

責(zé)任編輯:華軒 來源: 前端先鋒
相關(guān)推薦

2009-07-27 09:29:38

ASP.NET中Jav

2010-09-30 15:19:33

2009-10-12 10:33:11

Javascript替

2009-09-16 16:32:20

JavaScript靜

2009-07-17 16:41:48

actionPerfoSwing

2023-04-07 09:07:11

2023-03-09 12:30:55

2023-02-24 14:57:42

區(qū)塊鏈元宇宙人工智能

2021-07-27 22:56:00

JavaScript編程開發(fā)

2011-05-12 18:26:08

Javascript作用域

2024-08-13 15:23:37

2021-08-10 09:57:27

JavaScriptPromise 前端

2021-04-26 07:51:00

JavaScript方法函數(shù)

2016-10-13 19:33:10

javascript數(shù)組indexOf

2009-07-06 13:18:35

Servlet方法

2018-02-09 11:08:49

區(qū)塊鏈算法主流

2009-09-08 16:22:27

c# listBox

2009-05-21 09:24:42

表空間查詢Oracle

2016-09-06 21:37:41

2016-10-19 14:35:20

JavaScript函數(shù)式編程
點(diǎn)贊
收藏

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