温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JavaScript 中方法链的作用是什么

发布时间:2021-08-11 16:25:35 来源:亿速云 阅读:172 作者:Leah 栏目:web开发

本篇文章给大家分享的是有关JavaScript 中方法链的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

方法链的例子

在处理字符串时有两种方法。第一个种不用方法链,这要求必须在字符串上分别使用每个方法,这样必须每次都引用这个字符串。

第二种方式是用方法链。这时可以用所有想要的字符串方法。写出的代码也可以是单行或多行,这取决于你的习惯。而且只需要引用一次字符串。尽管结果相同,但是代码量却有很大的差异。

// 在字符串上使用方法链的例子 let myStr = ' - Hello-world. '  // 不用方法链: myStr = myStr.toLowerCase() myStr = myStr.replace(/-/g, ' ') myStr = myStr.trim()  // 用方法链: myStr = myStr.toLowerCase().replace(/-/g, ' ').trim()  // 多行方法链的写法: myStr = myStr   .toLowerCase()   .replace(/-/g, ' ')   .trim()  // 查看 "myStr" 的值 console.log(myStr) // Output: // 'hello world.'

在数组上也能用方法链:

// 在数组上使用方法链的例子 let myArray = [1, 7, 3, null, 8, null, 0, null, '20', 15]  // 不用方法链: myArray = myArray.filter(el => typeof el === 'number' && isFinite(el)) myArray = myArray.sort((x, y) => x - y)  // 使用方法链: myArray = myArray.filter(el => typeof el === 'number' && isFinite(el)).sort((x, y) => x - y)  // 多行方法链的写法: myArray = myArray   .filter(el => typeof el === 'number' && isFinite(el))   .sort((x, y) => x - y)  // 查看 "myArray" 的值. console.log(myArray) // Output: // [ 0, 1, 3, 7, 8 ]

Promise 是一个很好的例子,因为在使用时差不多全都是方法链。首先创建一个 promise,然后添加适当的处理函数。

// 创建 Promise const myPromise = new Promise((resolve, reject) => {   // 创建一个假延迟   setTimeout(function() {     // 用一条简单的消息解决诺言 promise     resolve('Sorry, no data.')   }, 1000) })  // 使用方法链: myPromise.then((data) => console.log(data)).catch(err => console.log(error))  // 多行方法链的写法: myPromise   .then((data) => console.log(data))   .catch(err => console.log(error)) // Output: // 'Sorry, no data.'

方法链是怎样工作的

接下来研究它是怎样工作的。答案很简单,是因为 this 。

假设有一个对象。如果在该对象内使用 this,它会引用这个对象。如果创建该对象的实例或副本,则 this  将会引用这个实例或副本。当你使用某些字符串或数组方法时,实际上是在用一个对象。

const myObj = {   name: 'Stuart',   age: 65,   sayHi() {     // 这里的 this 是 myObj 的引用     return `Hi my name is ${this.name}.`   },   logMe() {     console.log(this)   } }  myObj.sayHi() // Output: // 'Hi my name is Stuart.'  myObj.logMe() // Output: // { //   name: 'Stuart', //   age: 65, //   sayHi: ƒ, //   logMe: ƒ // }

如果是字符串,则使用的是原始数据类型。但是你所使用的方法例如 toLowerCase(),存在于 String  对象的原型中。在对象上使用方法链还有一个关键要素:this。

为了使链起作用,方法必须返回与其一起使用的对象,也就是必须返回 this。就像接力赛跑时的接力棒一样。

在 JavaScript  中实现方法链

为了使方法链有效,必须满足三个条件:首先,需要一些对象。其次,该对象需要一些以后可以调用的方法。第三,这些方法必须返回对象本身,它们必须返回  this 才能使用方法链。

让我们创建一个简单的对象 person。person 有 name, age 和 state 属性。state  用来表示当前处于什么状态。要想改变这个状态,需要用到几个方法:walk(), sleep(), eat(), drink(), work() 和  exercise()。

由于我们希望所有这些方法都是可链的,所以它们都必须返回 this。另外代码中还有一个用来把当前状态记录到控制台的工具方法。

// 创建 person 对象 const person = {   name: 'Jack Doer',   age: 41,   state: null,   logState() {     console.log(this.state)   },   drink() {     // 修改 person 的 state.     this.state = 'Drinking.'      // 把状态输出到控制台     this.logState()      // 返回 this 值。     return this   },   eat() {     this.state = 'Eating.'     this.logState()     return this   },   exercise() {     this.state = 'Exercising.'     this.logState()     return this   },   sleep() {     this.state = 'Sleeping.'     this.logState()     return this   },   walk() {     this.state = 'Walking.'     this.logState()     return this   },   work() {     this.state = 'Working.'     this.logState()     return this   } }  //  person   .drink() // Output: 'Drinking.'   .exercise() // Output: 'Exercising.'   .eat() // Output: 'Eating.'   .work() // Output: 'Working.'   .walk() // Output: 'Walking.'   .sleep() // Output: 'Sleeping.'  // 写在一行上 person.drink().exercise().eat().work().walk().sleep() // Output: // 'Drinking.' // 'Exercising.' // 'Eating.' // 'Working.' // 'Walking.' // 'Sleeping.'

方法、链、this 和箭头函数必须使用

也意味着无法使用箭头函数创建方法链。因为在箭头函数中,this 没有绑定到对象的实例,而是全局对象  window 的引用。如果返回 this,那么返回的不是对象本身而是 window。

另一个问题是从箭头函数内部访问和修改对象属性。由于 this 是全局对象 window,所以不能用它来引用对象及其属性。

如果你一定要使用箭头函数,必须想办法绕过这种方法。不用 this 来引用该对象,必须直接通过其名称引用该对象,也就是用对象名替换所有出现在箭头功能内的  this。

// 创建 person 对象 const person = {   name: 'Jack Doer',   age: 41,   state: null,   logState() {     console.log(this.state)   },   drink: () => {     person.state = 'Drinking.'      person.logState()      return person   },   eat: () => {     person.state = 'Eating.'      person.logState()      return person   },   exercise: () => {     person.state = 'Exercising.'      person.logState()      return person   },   sleep: () => {     person.state = 'Sleeping.'      person.logState()      return person   },   walk: () => {     person.state = 'Walking.'      person.logState()      return person   },   work: () => {     person.state = 'Working.'      person.logState()      return person   } }  //  person   .drink() // Output: 'Drinking.'   .exercise() // Output: 'Exercising.'   .eat() // Output: 'Eating.'   .work() // Output: 'Working.'   .walk() // Output: 'Walking.'   .sleep() // Output: 'Sleeping.'

这样做的缺点是灵活性不好。如果如果用Object.assign() 和  Object.create()复制对象,所有箭头函数仍然会硬连接到原始对象。

// 创建原始 person 对象 const person = {   name: 'Jack Doer',   age: 41,   state: null,   logState() {     // 打印整个对象     console.log(this)   },   drink: () => {     person.state = 'Drinking.'      person.logState()      return person   },   eat: () => {     person.state = 'Eating.'      person.logState()      return person   } }  // 让 person eat person.eat() // Output: // { //   name: 'Jack Doer', //   age: 41, //   state: 'Eating.', //   logState: ƒ, //   drink: ƒ, //   eat: ƒ // }  // 基于person对象创建新对象。 const newPerson = new Object(person)  // 修改 "name" 和 "age" 属性 newPerson.name = 'Jackie Holmes' newPerson.age = 33  // 让 newPerson drink。 // 这会打印 Jack Doer 而不是 Jackie Holmes。 newPerson.drink() // Output: // { //   name: 'Jack Doer', //   age: 41, //   state: 'Drinking.', //   logState: ƒ, //   drink: ƒ, //   eat: ƒ // }

但是,如果用 Object() 构造函数,就不会发生上述问题。如果用 new 关键字的和 Object()  构造造函数,将会创建独立的新对象。当你对这个新对象使用某个方法时,它将仅对这个新对象有效,而对原始对象无效。

// 创建原始 person 对象 const person = {   name: 'Jack Doer',   age: 41,   state: null,   logState() {     // 打印整个对象     console.log(this)   },   drink: () => {     person.state = 'Drinking.'      person.logState()      return person   },   eat: () => {     person.state = 'Eating.'      person.logState()      return person   } }  // 让 person eat. person.eat() // Output: // { //   name: 'Jack Doer', //   age: 41, //   state: 'Eating.', //   logState: ƒ, //   drink: ƒ, //   eat: ƒ // }  // 基于 person 对象创建新对象  const newPerson = new Object(person)  // 修改 "name" 和 "age" 属性 newPerson.name = 'Jackie Holmes' newPerson.age = 33  // 让 newPerson drink. newPerson.drink() // Output: // { //   name: 'Jackie Holmes', //   age: 33, //   state: 'Drinking.', //   logState: ƒ, //   drink: ƒ, //   eat: ƒ // }

如果你一定要用箭头功能,并想要复制对象的话,最好用 Object() 构造函数和 new 关键字创建这些副本。否则只需要用常规函数就够了。

方法链和类

如果你喜欢使用 JavaScript  类,也可以在JavaScript中使用方法链接。除了语法略又不同外,整个过程和对象是一样的。但是要注意所有可链的方法都必须返回 this。

// 创建 Person 类 class Person {   constructor(name, age) {     this.name = name     this.age = age     this.state = null   }    logState() {     console.log(this.state)   }    drink() {     this.state = 'Drinking.'      this.logState()      return this   }    eat() {     this.state = 'Eating.'      this.logState()      return this   }    sleep() {     this.state = 'Sleeping.'      this.logState()      return this   } }  // 创建 Person 类的实例 const joe = new Person('Joe', 55)  // 使用方法链 joe   .drink() // Output: 'Drinking.'   .eat() // Output: 'Eating.'   .sleep() // Output: 'Sleeping.'

以上就是JavaScript 中方法链的作用是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI