我很懶,我只想傳 fn 和 dependencies 兩個(gè)屬性,不想做額外的事情。好吧,我們來重構(gòu)一下構(gòu)造函數(shù):
var _setupTask = function(fn, level, name, dependencies) { if(typeof fn !== FUNCTION) { throw new Error('Invalid argument type: fn.'); } this.fn = fn; this.level = _validateLevel(level) ? level : LEVEL_NORMAL;
// detect type of name this.name = typeof name === STRING && name ? name : 't' + _id++;
// dependencies could be retrieved as an 'Object', so use instanceof instead. this.dependencies = dependencies instanceof Array ? dependencies : []; };
var T = SmartQueue.Task = function(task) { if(arguments.length > 1) { _setupTask.apply(this, arguments); } else { _setupTask.call(this, task.fn, task.level, task.name, task.dependencies); }
// init context/scope and data for the task. this.context = task.context || window; this.data = task.data || {}; };
如此一來,原來的構(gòu)造方式可以繼續(xù)工作,而上面的懶人可以這樣傳入一個(gè)“殘廢體”:
var task1 = new SmartQueue.Task({fn: obj.fn, dependencies: obj.dependencies});
當(dāng)構(gòu)造函數(shù)收到多個(gè)參數(shù)時(shí),按之前的方案等同處理;否則,視唯一的參數(shù)為 Task 對(duì)象或“殘廢體”。這里通過 JavaScript 中的 apply/call 方法將新實(shí)例傳給重構(gòu)出來的 _setupTask 方法,作為該方法的上下文 (context, 也有稱為 scope), apply/call 是 JavaScript 在方法之間傳遞上下文的法寶,要用心體會(huì)哦。同時(shí),允許用戶定義 task.fn 在執(zhí)行時(shí)的上下文,并將自定義的數(shù)據(jù)傳遞給執(zhí)行中的 fn.
經(jīng)典的 JavaScript 對(duì)象三段式是什么?
- 定義對(duì)象的構(gòu)造函數(shù)
- 在原型上定義屬性和方法
- new 對(duì)象,拿來用
所以,下面要為 SmartQueue.Task 對(duì)象的原型定義屬性和方法。上期分析過 Task (任務(wù))有幾個(gè)屬性和方法,部分屬性我們已經(jīng)在 _setupTask 中定義了,下面是原型提供的屬性和方法:
T.prototype = { enabled: true, register: function() { var queue = Q[this.level]; if(_findTask(queue, this.name) !== -1) { throw new Error('Specified name exists: ' + this.name); } queue.push(this); }, changeTo: function(level) { if(!_validateLevel(level)) { throw new Error('Invalid argument: level'); } level = parseInt(level, 10); if(this.level === level) { return; } Q[this.level].remove(this); this.level = level; this.register(); }, execute: function() { if(this.enabled) { // pass context and data this.fn.call(this.context, this.data); } }, toString: function() { var str = this.name; if(this.dependencies.length) { str += ' depends on: [' + this.dependencies.join(', ') + ']'; } return str; } };
如你所見,邏輯非常簡(jiǎn)單,也許你已經(jīng)在一分鐘內(nèi)掃過了代碼,嘴角不經(jīng)意間露出一絲心領(lǐng)神會(huì)。不過,這里要說的是簡(jiǎn)單而且通常最不被重視的 toString 方法。在一些高級(jí)語言中,為自定義對(duì)象實(shí)現(xiàn) toString 方法被作為最佳實(shí)踐準(zhǔn)則而推薦,為什么呢?因?yàn)?toString 可以很方便地在調(diào)試器中提供有用的信息,可以方便地將對(duì)象基本信息寫入日志;在統(tǒng)一的編程模式中,實(shí)現(xiàn) toString 可以讓你少寫一些代碼。
出處:Alipay UED
責(zé)任編輯:bluehearts
上一頁(yè) JavaScript組件之旅:編碼實(shí)現(xiàn)和算法 [1] 下一頁(yè) JavaScript組件之旅:編碼實(shí)現(xiàn)和算法 [3]
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|