前言:前不久阿里遠程面試時問了我一個問題,如下:
function Person(){};
var person = new Person(); //實現person.set(10).get()返回20
當時正在問我原型鏈的問題,所以面試官直接用我寫的person問的,我當時是這么實現的:
function Person(){};
var person = new Person(); person.set = function(n){ return { get:function(){ return n*2; }} }
返回結果其實也對,但set()和get()耦合太緊,不靈活。再聯想一下當時正在考我原型鏈,且面試開始時問了我jQuery的鏈式操作原理(沒答上來),所以感覺這題應該跟鏈式操作有關,於是上網查了查,確實是要用鏈式操作。先來看看鏈式操作的原理和js如何實現。
js實現鏈式操作
jQuery有一個十分強大的特點:鏈式操作。其實原理很簡單,就是每次方法執行完后返回this對象,這樣后面的方法就可以繼續在this環境下執行。先來實現一下:
//創建一個類
function Person(){};
//在原型上定義相關方法
Person.prototype ={ setName:function(){ this.name = name; return this; }, setAge:function(){ this.age = age; return this; } } //實例化 var person= new Person(); person.setName("Mary").setAge(20);
以上過程就實現了鏈式操作,而原理只是在每個方法調用后返回了this。jQuery中不用new一個實例化對象,所以可以將實例化過程封裝如下:
//將實例化過程封裝為一個函數
function newObj(){
return new Person(); } newObj().setName("Mary").setAge(20);
此時再想想上面的那道題,就很簡單了:
function Person(){};
//實現部分
Person.prototype ={ set:function(value){ this.value = value; return this; }, get:function(){ return this.value*2;//由於要返回值,且不需要繼續調用方法,所以不返回this } } var person = new Person(); console.log(person.set(10).get());//20
鏈式操作的優缺點
首先來說說缺點。
根據上面阿里面試題的實現,我們可以看出,get方法里不能返回this,因為有值需要返回。這就是鏈式操作的一個局限:只能應用在不需要返回值的情況下,或者只能最后一步需要返回值。jQuery主要是對DOM元素的操作,只需要改變DOM元素的表現而不需要返回值,所以適合鏈式操作。
再來說說優點。
js的執行環境為單線程,為了避免阻塞,我們時常用一些異步編程方式來完成一些可能產生阻塞的操作。常見的異步編程方式包括回調函數、事件監聽、ES6中的Promise對象。
鏈式操作實際上就是使得異步編程的流程更加清晰,不會像回調函數一樣相互耦合,難以分辨函數的執行順序且維護困難。ES6中的Promise也正是沿用了這一思想,每一個異步任務返回一個Promise對象,通過then方法指定回調函數。