JesseZhao1990 / blog

learing summary
MIT License
62 stars 7 forks source link

js中函数重载的实现 #112

Open JesseZhao1990 opened 6 years ago

JesseZhao1990 commented 6 years ago

什么叫函数的重载

简单的讲,函数重载就是具有相同的函数名,根据参数的不同干不同的事情的函数,

在js中如何实现函数的重载

在Java中,通过方法签名来唯一确定一个方法。所谓方法签名包括:方法名、参数类型和参数顺序、参数个数这几个要素。所以,如果两个方法名称相同,但是只要其他要素(例如参数类型、参数个数)不同,编译器就会认为是不同方法。从而可以存在同名的不同方法,导致了重载现象 但是在js中,方法完全靠js名来确定,不考虑参数类型和参数顺序,所以如果定义多个同名函数,后定义的会覆盖前边定义的。那是不是js没办法做到函数的重载呢?非也。。最起码我们能做到形式上重载,下面列举几个方法

1.根据传的参数的个数,动态执行不同的代码块。

function test(){
   if(arguments.length===0){
     console.log('0')
   }
   if(arguments.length===1){
     console.log('1')
   }
   if(arguments.length===2){
     console.log('2')
   }
}

test() //0
test(1) // 1
test(1,2) // 2

2.利用闭包

function addMethod(obj,name,fn){
  var old = obj[name];
  obj[name] = function(){
    if(fn.length === arguments.length){
      return fn.apply(this,arguments);
    }else if( typeof old === 'function'){
      return old.apply(this, arguments);
    }
  }
}

var utils = {};

addMethod(utils,'test',function(){
  console.log('test不传参');
})

addMethod(utils,'test',function(arg1){
  console.log('test传一个参数');
})

addMethod(utils, 'test', function(arg1,arg2){
  console.log('test传两个参数');
})

utils.test();   // test不传参
utils.test(1);  // test传一个参数
utils.test(1,2); // test传两个参数
JesseZhao1990 commented 6 years ago

知识点补充

1. function.length

一个函数的length代表了这个函数定义的参数的个数,和arguments.length的区别是arguments.length代表了函数执行时实际传入的参数的个数

2. 关于闭包

当调用一个闭包函数N次的时候,事实上是产生了N个闭包,这些闭包之间互相隔离。思考一下下面会输出什么?

function test(a){
  var b = a;
  return function(){
    console.log(b);
  }
}

var t1 = test(1);
var t2 = test(2);
var t3 = test(3);

t1();
t2();
t3();
t1();