JavaScript中的函数重载(Function overloading)

Overload:一种重载 JavaScript 函数的简单方法 重载.js 根据传递给函数的参数类型重载函数的简单方法。 用法 通过调用重载来创建一个采用不同类型和数量的参数的 mathod。 返回的方法可以像任何其他函数一样被调用。 var createPerson = overload ( [ String ] , function ( name ) { return "name: " + name ; } ) . when ( [ String , Number ] , function ( name , age ) { return createPerson ( name ) + ", age: " + age ; } ) . when ( [ String , Number , Function ] , function ( name , age , callback ) { return callback ( name , ag 立即下载
AI摘要

本文介绍了JavaScript中模拟函数重载的几种方法,包括通过参数数量和类型判断来执行不同操作。并通过具体示例展示了如何实现这些功能。

说明

JavaScript 中没有真正意义上的函数重载。

函数重载

函数名相同,函数的参数列表不同(包括参数个数和参数类型),根据参数的不同去执行不同的操作。

我们举个例子看看

function overload(a){
	console.log('一个参数')
}

function overload(a,b){
	console.log('两个参数')
}

// 在支持重载的编程语言中,比如 java
overload(1);   	  //一个参数
overload(1,2);    //两个参数


// 在 JavaScript 中
overload(1);   	  //两个参数
overload(1,2);    //两个参数

在JavaScript中,同一个作用域,出现两个名字一样的函数,后面的会覆盖前面的,所以 JavaScript 没有真正意义的重载。

但是有各种办法,能在 JavaScript 中模拟实现重载的效果。

先看第一种办法,通过 arguments 对象来实现

arguments 对象,是函数内部的一个类数组对象,它里面保存着调用函数时,传递给函数的所有参数。

function overload () {
  if (arguments.length === 1) {
    console.log('一个参数')
  }
  if (arguments.length === 2) {
    console.log('两个参数')
  }
}

overload(1);      //一个参数
overload(1, 2);  //两个参数

这个例子非常简单,就是通过判断 arguments 对象的 length 属性来确定有几个参数,然后执行什么操作。

但是参数少的情况下,还好,如果参数多一些,if 判断就需要写好多,就麻烦了。

所以,我们再来看一个经典的例子
在看这个例子之前,我们先来看一个需求,我们有一个 users 对象,users 对象的values 属性中存着一些名字。
一个名字由两部分组成,空格左边的是 first-name ,空格右边的是 last-name,像下面这样。

var users = {
  values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};

我们要在 users 对象 中添加一个 find 方法,

当不传任何参数时, 返回整个users .values;
当传一个参数时,就把 first-name 跟这个参数匹配的元素返回;
当传两个参数时,则把 first-name 和 last-name 都匹配的返回。

这个需求中 find方法 需要根据参数的个数不同而执行不同的操作,下来我们通过一个 addMethod 函数,来在 users 对象中添加这个 find 方法。

function addMethod (object, name, fn) {
  // 先把原来的object[name] 方法,保存在old中
  var old = object[name];

  // 重新定义 object[name] 方法
  object[name] = function () {
    // 如果函数需要的参数 和 实际传入的参数 的个数相同,就直接调用fn
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);

      // 如果不相同,判断old 是不是函数,
      // 如果是就调用old,也就是刚才保存的 object[name] 方法
    } else if (typeof old === "function") {
      return old.apply(this, arguments);
    }
  }
}

addMethod 函数,它接收3个参数
第一个:要绑定方法的对象,
第二个:绑定的方法名称,
第三个:需要绑定的方法

这个 addMethod 函数在判断参数个数的时候,除了用 arguments 对象,还用了函数的 length 属性。

函数的 length 属性,返回的是函数定义时形参的个数。

简单说 函数的 length 是,函数需要几个参数,而 arguments.length 是调用函数时,真的给了函数几个参数

function fn (a, b) {
  console.log(arguments.length)
}
console.log(fn.length);  // 2
fn('a');	// 1

下来我们来使用这个 addMethod 函数

// 不传参数时,返回整个values数组
function find0 () {
  return this.values;
}
// 传一个参数时,返回firstName匹配的数组元素
function find1 (firstName) {
  var ret = [];
  for (var i = 0; i < this.values.length; i++) {
    if (this.values[i].indexOf(firstName) === 0) {
      ret.push(this.values[i
      ]);
    }
  }
  return ret;
}
// 传两个参数时,返回firstName和lastName都匹配的数组元素
function find2 (firstName, lastName) {
  var ret = [];
  for (var i = 0; i < this.values.length; i++) {
    if (this.values[i
    ] === (firstName + " " + lastName)) {
      ret.push(this.values[i
      ]);
    }
  }
  return ret;
}
// 给 users 对象添加处理 没有参数 的方法
addMethod(users, "find", find0);

// 给 users 对象添加处理 一个参数 的方法
addMethod(users, "find", find1);

// 给 users 对象添加处理 两个参数 的方法
addMethod(users, "find", find2);

// 测试:
console.log(users.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
console.log(users.find("Dean")); //["Dean Edwards", "Dean Tom"]
console.log(users.find("Dean","Edwards")); //["Dean Edwards"]

addMethod 函数是利用了闭包的特性,通过变量 old 将每个函数连接了起来,让所有的函数都留在内存中。

每调用一次 addMethod 函数,就会产生一个 old,形成一个闭包。
我们可以通过 console.dir(users.find) ,把 find 方法打印到控制台看看。

上面这个例子是 jQuery 之父 John Resig 写的,他在他的博客和他写的书 《secrets of the JavaScript ninja》第一版中都有提到过,在书中的第4章中也有讲解 Function overloading,文中的 addMethod 函数 就是书中的例子 4.15,感兴趣的朋友可以去看看。

上面的例子,本质都是在判断参数的个数,根据不同的个数,执行不同的操作,而下来举的例子是通过判断参数的类型,来执行不同的操作。

我们看看 jQuery 中的 css( ) 方法。

css( ) 方法返回或设置匹配的元素的一个或多个样式属性。

css(name|pro|[,val|fn])

我们可以看到 css( ) 方法,有5种 参数情况,其中3种是一个参数,另外两种是两个参数。
而在只有一个参数的情况下,如果参数类型是字符串或者数组就是获取属性值,而如果参数是对象,就是是设置属性值。

jQuery 的 css( ) 方法就是通过判断参数的类型,来确定执行什么操作。

我们来看看jQuery 3.3.1中的源码

// name 表示属性名
// value 表示属性值
css: function( name, value ) {
	return access( this, function( elem, name, value ) {
		var styles, len,
			map = {},
			i = 0;

		// 判断属性名是不是数组
		// 是数组就遍历,调用jQuery.css 方法传入每个属性名,获取样式
		if ( Array.isArray( name ) ) {
			styles = getStyles( elem );
			len = name.length;

			for ( ; i < len; i++ ) {
				map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
			}

			return map;
		}

		// 如果value 不等于 undefined 就调用jQuery.style 方法设置样式
		// 如果value 等于 undefined 就调用jQuery.css 方法获取样式
		return value !== undefined ?
			jQuery.style( elem, name, value ) :
			jQuery.css( elem, name );
	}, name, value, arguments.length > 1 );
}

css( ) 方法依赖于三个方法:

1、jQuery.access( ) 方法,这个方法可以获取 或 设置,一个或者多个属性值

jQuery.access( ) 方法里有这样的代码

// 设置多个属性值
// 如果属性名(key)的类型是 object,就遍历这个对象
// 遍历一次就调用一次 access()方法,并传入这次的属性名和属性值
if ( jQuery.type( key ) === "object" ) {
	chainable = true;
	for ( i in key ) {
		jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
	}

// 设置一个值
} else if ( value !== undefined ) {
	......
}

也就是这个方法,在帮 css( ) 方法判断第一个参数是字符串还是对象的。

2、jQuery.style( ) 方法:在DOM节点上读取或设置样式属性

在css( )方法中,如果有传第二个参数,也就是有要设置的属性值时,那就会调用 jQuery.style( ) 方法设置样式

3、jQuery.css( ) :在DOM元素上读取DOM样式值

这里的 jQuery.css( ) 是通过 jQuery.extend( ) 添加的方法,而我们最开始提到的 css( )方法,是通过 jQuery.fn.extend( ) 添加的方法,他们不是同一个方法。

jQuery.extend( )与 jQuery.fn.extend( )的区别

jQuery.extend( )是为jQuery类添加类方法(静态方法),需要通过jQuery类来调用(直接使用 $.xxx 调用);

jQuery.fn.extend( )是为jQuery类添加成员数(实例方法),所有jQuery实例都可以直接调用(需要使用 $().xxx 调用)。

重载的好处

重载其实是把多个功能相近的函数合并为一个函数,重复利用了函数名。
假如jQuery中的css( )方法不使用 重载,那么就要有5个不同的函数,来完成功能,那我们就需要记住5个不同的函数名,和各个函数相对应的参数的个数和类型,显然就麻烦多了。

总结

虽然 JavaScript 并没有真正意义上的重载,但是重载的效果在JavaScript中却非常常见,比如 数组的 splice( )方法,一个参数可以删除,两个参数可以删除一部分,三个参数可以删除完了,再添加新元素。
再比如 parseInt( )方法 ,传入一个参数,就判断是用十六进制解析,还是用十进制解析,如果传入两个参数,就用第二个参数作为数字的基数,来进行解析。

文中提到的实现重载效果的方法,本质都是对参数进行判断,不管是判断参数个数,还是判断参数类型,都是根据参数的不同,来决定执行什么操作的。

虽然,重载能为我们带来许多的便利,但是也不能滥用,不要把一些根本不相关的函数合为一个函数,那样并没有什么意义。

参考

浅谈JavaScript函数重载

js如何实现重载

JavaScript函数重载

这里写图片描述

overload-js:javascript中的函数重载 重载-js JavaScript 中的函数重载为 3.9KB,压缩为 1.4KB。 提供工具来模拟大多数严格类型语言中存在的。 防止难以阅读和维护的混乱、冗长、if 语句、类型检查函数。 受和启发的样式和 API。 npm install overload-js 基本用法 var hello = ( function ( ) { var secret = '!' ; return overload ( ) . args ( ) . use ( function ( ) { return secret ; } ) . args ( String ) . use ( function ( val ) { secret = val ; } ) ; } ( ) ) ; hello ( 'world' ) ; // calls setter hello ( 立即下载

相关推荐

超详细 | 贝叶斯网络基础——有图有真相

Hello,大家好,我是starz。这是本系列的第二篇《概率基础Ⅱ》,虽说是概率基础,但作为过渡,它开始以图为载体 这节的主要内容有: 贝叶斯网络 三种结构 D-划分 贝叶斯球 马尔科夫毯 应用例子 总结 让我们开始吧 :3 贝叶斯网络 概率图模型可笼统分为两类,一是基于无向图的马尔科夫网络: 二是基于有向图的贝叶斯...

qq_41603411的博客 2万+

Typescript | 函数重载overload、构造函数重载

 (+1 overload) function foo(x: string): string function foo(x: number, y: number): number function foo(x?, y?): any { if (typeof y !== 'undefined') { return x + y } return x } foo('hello'...

u011607490的博客 7174

JS 函数(二): overload

<!DOCTYPE html> <html> <head> <title>01_define.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page">

yoyov的博客 474

USRP B210 运行gnuradio时 FPGA固件版本冲突错误解决方法

事情起源于昨天拿到USRP后开始调试,结果整了一个下午都没解决这个问题。 昨天晚上自己思考了一下,觉得还是版本问题。 首先,uhd_find_devices和uhd_usrp_probe均可以正常运行,没有报错,固件正常加载,序列号也可看到。 teray@teray-X550JK:~$ uhd_find_devices [INFO] [UHD] linux; GNU C++ version 7.5...

斯哈研究所 4243

新手必看:如何用T265和ROS实现无人机室内精准定位(附PX4参数配置)

本文详细介绍了如何使用Intel Realsense T265和ROS实现无人机室内精准定位,包括硬件准备、ROS数据流架构设计、PX4参数配置及系统验证。特别针对视觉SLAM技术在室内环境中的应用,提供了从零搭建到进阶优化的全流程解析,适合无人机开发新手快速上手。

weixin_30642561的博客 404

JS中的函数重载 实参 形参 arguments

在Java中,方法可以进行重载 function add(int a,int b){ //代码块 } function add(int a,int b,int c){ //代码块 } 调用的时候,会根据传入参数的不同,自动调用不同的方法。 那么在JS中呢? 如果在js中存在一个方法kid(p1,p2,p3),在别处进行调用的时候,少传了一个参数p3,会是什么结果呢?...

Sail__的专栏 547

CAN总线入门(硬件部分)

这篇博客讲述CAN总线入门知识。

记得诚 1万+

JS中的重载——如何实现一个类似这样的功能,我也想玩玩

在js中主要有以下几种实现重载的方式: 1. 使用剩余参数的形式来接收可变的参数,并通过一些判断手段来处理不同情况的逻辑。 2. 使用arguments的形式,来动态判断需要执行的操作 3. 使用proxy的形式来拦截函数的行为,以达到控制不同的逻辑分支 ......

zhang_hai_cheng的博客 628

QT实现OPCUA服务端客户端(附完整源码)

QT实现OPCUA服务端客户端(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1818

RT-DETR改进前必看 - Ultralytics调参 1:1还原RT-DETR官方版本实验环境,更方便改进

的项目文件中集成了YOLOv3v5v6v8v9v10rt-detr11以及其中不同大小的模型结构,更方便我们学习和使用。的参数配置在路径下,其中中设置了模型在训练Train验证Val/Test预测Predict可视化Visualize导出Export超参数Hyperparameters、以及跟踪Tracker的相关参数。在调参过程中主要涉及训练Train和超参数Hyperparameters。下面主要介绍一下初始超参数Hyperparameters。

Limiiiing的博客 7959

[Javascript]:JS数据类型、类型判断、函数function与Function的使用

因为之前学过Java,在学习JS时,对JS的数据类型、function和Function的使用概念容易搞混淆,理解不怎么深刻。遂将这些知识点和概念梳理一遍,以便自己和他人理解。如有错误,敬请谅解。       知识点会涉及到:JS数据类型、JS的类型判断方式、函数创建方式、function与Function的区别、匿名函数的使用、函数特点以及函数重载问题。 Javascript数据类型

我只是个程序员。 1万+

【AI智能体】AI 编程 + 飞书CLI + Skills 重塑开发新范式实战操作详解

AI 编程 + 飞书CLI + Skills 重塑开发新范式实战操作详解

congge 3664

JavaScript 中的函数重载

问题一:什么是函数重载?重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个运算符完成不同的运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。当然,不只是 C++,其它面向对象语言如 Java 也对函数重载有着原生支持。重载的核心是这些同名函数参数

青天的博客 698

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

JavaScript中的Function

*

hao1210119的博客 1710

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

JavaScript中的function使用方法

JavaScript入门易,可深究起来,竟搞得我如此混乱,这恐怕就是弱类型语言的特点吧?写惯了C++,还真是不适应。近日在google上搜来搜去,学习了半天function、this和prototype,这就总结一下,但愿能把它们理清楚。这是第一篇,关于JavaScript中的function。参考了一些文章,我认为JavaScript中的function可以有以下两种用法:一是做“普通逻辑代码容

小曰免的实验室 5663

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

JavaScript中的Function类型及函数、匿名函数等

函数与Function的关系:每个函数都是Funtion类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。 函数的定义方式 1.函数声明 以关键字function开始,后面跟随函数名称标识符、一对圆括号(包含有0个或多个用逗号隔开的函数参数名称)和一对花括号(包含0条或多条JS语句,构成函数体)。解析器在向执行...

Eternal_tyq的博客 609

JS深入浅出Function与构造函数

文章来源: 学习通http://www.bdgxy.com/ 目录?1.概述1.1利用Function构造函数创建函数1.2Function与Object2.构造函数2.1自定义否则函数2.2对象的constructor属性2.3构造函数与函数3.Function对象的属性和方法3.1length属性3.2call()方法4.Arguments对象5.总结?1.概述 Function是一个构造函数,可以通过该构造函数去创建一个函数,创建的函数是一个Function对象,实际上,不管使用什么方式创建的都

菜鸟教程 1564

Javascript-js不允许函数重载

Javascript-js不允许函数重载 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript"> function fun(a,b) { alert("有参函数fun(a,b)")

我就吃一口的BLOG 520

JavaScript的数组、函数的两种定义方式、js中的函数不允许重载

JavaScript的数组、函数的两种定义方式、js中的函数不允许重载

weixin_46065214的博客 260

JavaScript中的function

1.使用function声明方法和类型   可以使用function声明一个方法,比如:  function testMethod() {   alert("Hello world"); }  testMethod();   //输出"Hello world!" 除了方法,function还可以用来声明"类型"。JavaScript中本没有"类型"的概念,也就是Class的概念,但可以

hellogull 2172

JS高级之深入浅出Function与构造函数

大家好,我是一碗周,一个不想被喝(内卷)的前端。如果写的文章有幸可以得到你的青睐,万分有幸~ 概述 Function是一个构造函数,可以通过该构造函数去创建一个函数,创建的函数是一个Function对象,实际上,不管使用什么方式创建的都是一个Function对象,本质上函数名仅仅是一个变量名,它指向某个Function对象的引用。 验证代码如下所示: var f = function () { console.log('this is f function'); } // 函数也是一个对象 cons.

一碗周 689

html中js函数定义方式,JavaScript深入理解函数 - 函数的定义

在JavaScript中,函数是一个非常特殊的对象。每一个函数都是一个Function类型的实例,它们和其它引用类型一样具有属性和方法。由于函数是对象,所以函数名实际上是一个指向函数的指针,不会与某个函数绑定。函数在内存中存储的操作其实是通过一个键值对来存储的。我们可以通过下面的方式来定义一个函数:function fn1(){console.info("函数1");}我们可以使用typeof关键...

weixin_42099151的博客 930

JavaScript的Function 类型

注:原文出处:https://www.cnblogs.com/whiteMu/p/7399719.html 一,Function定义   Function实际上是对象,与其他引用类型一样具有属性和方法。Function可以通过三种方法进行定义,分别是函数声明语法定义,函数表达式定义和Function构造函数定义。   1.函数声明语法定义 function functionName(v...

mystonelxj的博客 5143

java js中 function函数报错_function函数

我们知道,在js中,函数实际上是一个对象,每个函数都是function函数类型的实例,并且都与其他引用类型一样具有属性和方法。因此,函数名实际上是指向函数对象的指针,不与某个函数绑定。在常见的两种定义方式(见下文)之外,还有一种定义的方式能更直观的体现出这个概念:var sum = new Function("num1", "num2", "return num1 + num2"); //不推荐F...

weixin_31018573的博客 857
上一篇: 一个浪漫又悲情的爱情故事——笛卡尔心形线
下一篇: 毕业一年时的反思
FEWY
FEWY 领域专家: 前端开发技术领域 领域专家: 前端开发技术领域
博客等级 码龄10年 504粉丝 77原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值