javascript高级知识点——函数的长度
代码信息来自于http://ejohn.org/apps/learn/。
函数的长度属性如何工作?
function makeNinja(name){} function makeSamurai(name, rank){} console.log( makeNinja.length == 1, "只定义了一个形参" ); console.log( makeSamurai.length == 2, "定义了两个形参" );
很清楚,函数的长度就是定义形参的个数。
我们可以利用这一点写重载函数
function addMethod(object, name, fn){ // 存储对过去方法的引用 var old = object[ name ]; // 重写新的方法 object[ name ] = function(){ // 核对定义形参的个数, // 与我们接受接收参数的个数 if ( fn.length == arguments.length ) // 如果匹配运行这个函数 return fn.apply( this, arguments ); // 否则调用过去的方法 else if ( typeof old === "function" ) return old.apply( this, arguments ); }; }
来看一看重载函数的运用
function addMethod(object, name, fn){ // 存储对过去方法的引用 var old = object[ name ]; // 重写新的方法 object[ name ] = function(){ // 核对定义形参的个数, // 与我们接受接收参数的个数 if ( fn.length == arguments.length ) // 如果匹配运行这个函数 return fn.apply( this, arguments ); // 否则调用过去的方法 else if ( typeof old === "function" ) return old.apply( this, arguments ); }; } function Ninjas(){ var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell" ]; addMethod(this, "find", function(){ return ninjas; }); addMethod(this, "find", function(name){ var ret = []; for ( var i = 0; i < ninjas.length; i++ ) if ( ninjas[i].indexOf(name) == 0 ) ret.push( ninjas[i] ); return ret; }); addMethod(this, "find", function(first, last){ var ret = []; for ( var i = 0; i < ninjas.length; i++ ) if ( ninjas[i] == (first + " " + last) ) ret.push( ninjas[i] ); return ret; }); } var ninjas = new Ninjas(); console.log( ninjas.find()); console.log( ninjas.find("Sam")); console.log( ninjas.find("Dean", "Edwards")); console.log( ninjas.find("Alex", "X", "Russell"));
实例化ninja时,向ninja执行了4次添加方法,每次都覆盖在find属性上,根据闭包的作用域链,新的方法仍然可以引用addMethod里old,old保存的是上一个方法。
最后的find就是判断参数,与形参数量是否相同,是就执行,不是就调用old的方法。如此反复。
等同于以下代码
var ninjas = { find: function(){ var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell"] var old = function(){ var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell"] var old = function(){ var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell"] var old; var fn = function(){ return ninjas; } if ( fn.length == arguments.length ) { return fn.apply( this, arguments ); }else if ( typeof old === "function" ) { return old.apply( this, arguments ); } }; var fn = function(name){ var ret = []; for ( var i = 0; i < ninjas.length; i++ ) if ( ninjas[i].indexOf(name) == 0 ) ret.push( ninjas[i] ); return ret; } if ( fn.length == arguments.length ) { return fn.apply( this, arguments ); }else if ( typeof old === "function" ) { return old.apply( this, arguments ); } } var fn = function(first, last){ var ret = []; for ( var i = 0; i < ninjas.length; i++ ) if ( ninjas[i] == (first + " " + last) ) ret.push( ninjas[i] ); return ret; } if ( fn.length == arguments.length ) { return fn.apply( this, arguments ); }else if ( typeof old === "function" ) { return old.apply( this, arguments ); } }, } console.log( ninjas.find()); console.log( ninjas.find("Sam")); console.log( ninjas.find("Dean", "Edwards")); console.log( ninjas.find("Alex", "X", "Russell"));