方法链是一种流行的编程方法,可以帮助您编写更简洁和可读性更高的代码。在本文中,我们将一起学习JavaScript中的方法链是什么以及它是如何工作的。我们还将探讨如何使用方法链来提高代码质量和可读性。JavaScript中的方法链你一定用过像jQuery这样的库,你可能见过类似的东西。级联时主要有两种方式:一种是依次执行方法,另一种是在同一行执行方法。这种做法在纯JavaScript中也很常见。你可以在数组、字符串和承诺中看到它。在这些情况下,所有程序都是相同的。首先引用要使用的对象。然后根据需要使用尽可能多的方法。但是不要单独使用这些方法,而是一个接一个地使用它们。基本上将它们链接在一起。我们先来看一些例子。方法链接示例处理字符串时有两种方法。第一种不使用方法链,要求每个方法都必须在字符串上单独使用,这样每次都必须引用字符串。第二种方法是使用方法链。此时你可以使用所有你想要的字符串方法。写的代码也可以是单行的,也可以是多行的,看你的习惯。而且你只需要引用一次字符串。虽然结果一样,但是代码量却相差巨大。//字符串上的方法链接示例)//使用方法链:myStr=myStr.toLowerCase().replace(/-/g,'').trim()//多行方法链的写法:myStr=myStr.toLowerCase().replace(//g,'').trim()//查看"myStr"的值console.log(myStr)//Output://'helloworld.'也可以在数组上使用方法链://在数组中使用方法链上面的例子letmyArray=[1,7,3,null,8,null,0,null,'20',15]//不要使用方法链:myArray=myArray.filter(el=>typeofel==='number'&&isFinite(el))myArray=myArray.sort((x,y)=>x-y)//使用方法链:myArray=myArray.filter(el=>typeofel==='number'&&isFinite(el)).sort((x,y)=>x-y)//多行方法链的写法:myArray=myArray.filter(el=>typeofel==='number'&&isFinite(el)).sort((x,y)=>x-y)//查看"myArray"的值.console.log(myArray)//输出://[0,1,3,7,8]Promise是一个很好的例子,因为几乎都是方法链。首先创建一个承诺,然后添加适当的处理程序。//创建一个PromiseconstmyPromise=newPromise((resolve,reject)=>{//创建一个伪延迟setTimeout(function(){//用一个简单的消息解决这个promisepromisesolve('Sorry,nodata.')},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,nodata.'方法链是如何工作的接下来研究怎么运行的。答案很简单,因为这个。假设有一个对象。如果在这个对象内部使用this,它会引用这个对象。如果创建了此对象的实例或副本,则this将引用此实例或副本。当您使用某些字符串或数组方法时,您实际上是在使用一个对象。constmyObj={name:'Stuart',age:65,sayHi(){//这里引用myObjreturn`Himynameis${this.name}.`},logMe(){console.log(this)}}myObj.sayHi()//Output://'HimynameisStuart.'myObj.logMe()//Output://{//name:'Stuart',//age:65,//sayHi:?,//logMe:?//}如果是字符串,则使用原始数据类型。但是你使用的方法,比如toLowerCase(),存在于String对象的原型中。在对象上使用方法链还有另一个关键要素:this。要使链接起作用,方法必须返回与其一起使用的对象,这意味着它必须返回this。就像接力赛中的接力棒。在JavaScript中实现方法链为了使方法链起作用,必须满足三个条件:首先,您需要一些对象。其次,对象需要一些可以稍后调用的方法。第三,方法必须返回对象本身,并且必须返回this才能使用方法链接。让我们创建一个简单的对象person。人有姓名、年龄和状态属性。state用于指示当前处于什么状态。要更改此状态,使用了几个方法:walk()、sleep()、eat()、drink()、work()和exercise()。由于我们希望所有这些方法都是可链接的,因此它们都必须返回this。另外,代码中还有一个工具方法,可以将当前状态记录到控制台。//创建person对象constperson={name:'JackDoer',age:41,state:null,logState(){console.log(this.state)},drink(){//修改state.this.stateoftheperson='Drinking.'//输出状态到控制台this.logState()//返回这个值。returnthis},eat(){this.state='Eating.'this.logState()returnthis},exercise(){this.state='Exercising.'this.logState()returnthis},sleep(){this.state='Sleeping.'this.logState()returnthis},walk(){this.state='Walking.'this.logState()returnthis},work(){this.state='Working.'this.logState()returnthis}}//person.drink()//输出:'Drinking.'.exercise()//输出:'Exercising.'.eat()//输出:'Eating.'.work()//输出:'Working.'.walk()//Output:'Walking.'.sleep()//Output:'Sleeping.'//写在一行上person.drink().exercise().eat().work().walk().sleep()//Output://'Drinking.'//'Exercising.'//'Eating.'//'Working.'//'Walking.'//'Sleeping.'必须使用method、chain、this和箭头函数也意味着不能使用箭头函数来创建方法链。因为在箭头函数中,this并没有绑定对象的实例,而是对全局对象window的引用。如果返回this,则返回的不是对象本身,而是窗口。另一个问题是从箭头函数内部访问和修改对象属性。由于这是全局对象窗口,因此不能用于引用对象及其属性。如果一定要使用箭头函数,就必须想办法绕过这个方法。不是使用this来引用对象,而是必须通过其名称直接引用对象,即将箭头函数中所有出现的this替换为对象名称。//创建一个人对象constperson={name:'JackDoer',age:41,state:null,logState(){console.log(this.state)},drink:()=>{person.state='Drinking.'person.logState()returnperson},eat:()=>{person.state='Eating.'person.logState()returnperson},exercise:()=>{person.state='Exercising.'person.logState()returnperson},sleep:()=>{person.state='Sleeping.'person.logState()returnperson},walk:()=>{person.state='Walking.'person.logState()returnperson},work:()=>{person.state='Working.'person.logState()returnperson}}//person.drink()//Output:'Drinking.'.exercise()//Output:'Exercising.'.eat()//Output:'Eating.'.work()//Output:'Working.'.walk()//Output:'Walking.'.sleep()//Output:'Sleeping.'缺点是灵活性不好。如果您使用Object.assign()和Object.create()复制对象,所有箭头函数仍将硬连线到原始对象。//创建原始人对象constperson={name:'JackDoer',age:41,state:null,logState(){//打印整个对象console.log(this)},drink:()=>{person.state='Drinking.'person.logState()returnperson},eat:()=>{person.state='Eating.'person.logState()returnperson}}//让personeatperson.eat()//输出://{//name:'JackDoer',//age:41,//state:'Eating.',//logState:?,//drink:?,//eat:?//}//基于创建在人对象上的新对象。constnewPerson=newObject(person)//修改“name”和“age”属性newPerson.name='JackieHolmes'newPerson.age=33//让newPerson喝水。//这会打印JackDoer而不是JackieHolmes。newPerson.drink()//Output://{//name:'JackDoer',//age:41,//state:'Drinking.',//logState:?,//drink:?,//eat:?//}但是如果使用Object()构造器,就不会出现上面的问题。如果与new关键字和Object()构造函数一起使用,将创建一个独立的新对象。当你在这个新对象上使用一个方法时,它只会作用于这个新对象,而不作用于原来的对象。//创建原始人对象constperson={name:'JackDoer',age:41,state:null,logState(){//打印整个对象console.log(this)},drink:()=>{person.state='Drinking.'person.logState()returnperson},eat:()=>{person.state='Eating.'person.logState()returnperson}}//让personeat.person.eat()//输出://{//name:'JackDoer',//age:41,//state:'Eating.',//logState:?,//drink:?,//eat:?//}//基于person对象创建新对象constnewPerson=newObject(person)//修改“name”和“age”属性newPerson.name='JackieHolmes'newPerson.age=33//makenewPersondrink.newPerson.drink()//输出://{//name:'JackieHolmes',//age:33,//state:'Drinking.',//logState:?,//drink:?,//eat:?//}如果必须的话使用箭头函数,并想要复制对象,最好使用Object()构造函数和new关键字来创建这些副本。否则只需使用常规功能。方法链和类如果您更喜欢使用JavaScript类,您也可以在JavaScript中使用方法链。整个过程与对象相同,只是语法略有不同。但请注意,所有可链接的方法都必须返回this。//创建一个Person类classPerson{constructor(name,age){this.name=namethis.age=agethis.state=null}logState(){console.log(this.state)}drink(){this.state='Drinking.'this.logState()returnthis}eat(){this.state='Eating.'this.logState()returnthis}sleep(){this.state='Sleeping.'this.logState()returnthis}}//创建Person类的实例constjoe=newPerson('Joe',55)//使用方法链joe.drink()//Output:'Drinking.'.eat()//Output:'Eating.'.sleep()//Output:'Sleeping.'摘要方法链非常有用,它可以帮助您编写更短、更易读的代码。
