#
var count = 10000000; var MyClass = function(a) { this.a = a; } //链式 MyClass.prototype.foo = function(b) { this.a += b; return this; } //非链式 MyClass.prototype.foo2 = function(b) { this.a += b; } var obj = new MyClass(5); var start = new Date().getTime(); for (var index = 0; index < count; index++) { obj.foo(1).foo(2).foo(3); } var end = new Date().getTime(); var obj2 = new MyClass(5); var start2 = new Date().getTime(); for (var index = 0; index < count; index++) { obj2.foo2(1); obj2.foo2(2); obj2.foo2(3); } var end2 = new Date().getTime(); console.log(obj.a + "返回 this: " + (end - start) + "ms");//88ms console.log(obj2.a + "不返回 this: " + (end2 - start2) + "ms");//66ms
#Lazy evaluation
function Lazy() { this.chain = []; return this; } Lazy.prototype.add = function(fn) { this.chain.push(fn.bind.apply(fn, [this].concat([].slice.call(arguments, 1)))); return this; } Lazy.prototype.invoke = function(obj) { return this.chain.reduce(function(obj, fn) { return fn.apply(this, obj); }, obj); } function Lazy() { this.functionsList = []; } Lazy.prototype = { constructor: Lazy, add: function(fn) { this.functionsList.push(Function.prototype.bind.apply(fn, arguments)); return this; }, invoke: function() { var firstFunction = this.functionsList[0], restFunctionsList = this.functionsList.slice(1); return restFunctionsList.reduce(function(prevArgs, fn) { return fn.apply(this, prevArgs); }, firstFunction.apply(this, arguments[0])); } }; new Lazy() .add(filterNumbers) .add(filterRange, 2, 7) .add(max) .invoke([1, 8, 6, [], "7", -1, {v: 5}, 4]); //6 filterNumbers(1, 8, 6, [], "7", -1, {v: 5}, 4) // == [1, 8, 6, -1, 4] // ^------------------------------ from invoke filterRange(2, 7, 1, 8, 6, -1, 4) // == [6, 4] // from add ---^ ^------------- from previous result max(6, 4) // == 6 // ^--- from previous result Result from invoke: 6 // ^ from last result function max() { return Math.max.apply(null, arguments); } function filterNumbers() { return Array.prototype.filter.call(arguments, function(value) { return isNumeric(value); }); } function isNumeric(n) { return !isNaN(n) && Number(n) === n; } function filterRange(min, max) { var args = Array.prototype.slice.call(arguments, 2); return Array.prototype.filter.call(args, function(value) { return min <= value && value <= max; }); }