搜索
您的当前位置:首页正文

EffectiveJavaScriptItem55接受配置对象作为函数参数

2023-12-01 来源:欧尚宠物网

虽然保持函数接受的参数的顺序很重要,但是当函数能够接受的参数达到一定数量时,也会让用户很头疼:

var alert = new Alert(100, 75, 300, 200, "Error", message, "blue", "white", "black", "error", true);

随着函数的不断重构和进化,它能够接受的参数也许会越来越多,最终就像上面的例子那样。

对于这种情况,JavaScript可以使用一个配置对象来替代以上的所有参数:

var alert = new Alert({ x: 100, y: 75, width: 300, height: 200, title: "Error", message: message, titleColor: "blue", bgColor: "white", textColor: "black", icon: "error", modal: true});

这样做虽然会让代码稍微冗长一些,但是毫无疑问它的好处是很明显的:配置对象中的每个属性的名字就好比是一份文档,来告诉用户这个属性是干什么用的。特别是对于布尔值,单独的传入true和false是很难判断它的真实意图的。

使用这种方式的另外一个好处是,所有的属性都是可选的。如果配置对象中没有出现某个属性,那么就是用默认值来代替它。

var alert = new Alert(); // use all default parameter values

如果函数需要接受必须的参数,那么最好还是将它放在配置对象的外面,就像下面这样:

var alert = new Alert(app, message, { width: 150, height: 100, title: "Error", titleColor: "blue", bgColor: "white", textColor: "black", icon: "error", modal: true});

配置对象中的所有属性都是函数能够接受的可选参数,而app和message则是必须要传入的参数。

对于配置对象的处理,可以像下面这样:

function Alert(parent, message, opts) { opts = opts || {}; // default to an empty options object this.width = opts.width === undefined ? 320 : opts.width; this.height = opts.height === undefined ? 240 : opts.height; this.x = opts.x === undefined ? (parent.width / 2) - (this.width / 2) : opts.x; this.y = opts.y === undefined ? (parent.height / 2) - (this.height / 2) : opts.y; this.title = opts.title || "Alert"; this.titleColor = opts.titleColor || "gray"; this.bgColor = opts.bgColor || "white"; this.textColor = opts.textColor || "black"; this.icon = opts.icon || "info"; this.modal = !!opts.modal; this.message = message;}

对于可选的配置对象,首先使用Item 54中介绍的方法当它在真值判断中返回false时,使用空对象替换它。

上述的代码还有进一步优化的空间:通过使用对象扩展或者合并的函数。在很多JavaScript的库和框架中都有一个extend函数,它接受一个目标对象和一个源对象,然后将源对象中的属性拷贝到目标对象中:

function Alert(parent, message, opts) { opts = extend({ width: 320, height: 240 }); opts = extend({ x: (parent.width / 2) - (opts.width / 2), y: (parent.height / 2) - (opts.height / 2), title: "Alert", titleColor: "gray", bgColor: "white", textColor: "black", icon: "info", modal: false }, opts); this.width = opts.width; this.height = opts.height; this.x = opts.x; this.y = opts.y; this.title = opts.title; this.titleColor = opts.titleColor; this.bgColor = opts.bgColor; this.textColor = opts.textColor; this.icon = opts.icon; this.modal = opts.modal;}

通过extend函数,不再需要时常对每个属性进行判断。上述代码中的第一个extend函数用来在width和height属性没有被设置使设置默认值,因为在第二个extend函数中会根据它们进行计算。

如果所有的属性最终会被赋值到this对象上,那么以上代码可以简化成下面这样:

function Alert(parent, message, opts) { opts = extend({ width: 320, height: 240 }); opts = extend({ x: (parent.width / 2) - (opts.width / 2), y: (parent.height / 2) - (opts.height / 2), title: "Alert", titleColor: "gray", bgColor: "white", textColor: "black", icon: "info", modal: false }, opts); extend(this, opts);}

extend函数的实现通常都会遍历源对象的属性,然后如果该属性的值不是undefined时,会将它拷贝到目标对象上:

function extend(target, source) { if (source) { for (var key in source) { var val = source[key]; if (typeof val !== "undefined") { target[key] = val; } } } return target;}

总结

使用可选的配置对象来让API更具可读性。

配置参数中的属性都应该是函数的可选参数。

使用extend工具函数来简化使用了配置对象的代码。

小编还为您整理了以下内容,可能对您也有帮助:

如何学习JS

如何学习JS,在使用JS的过程中有很关键的小技巧,掌握了这个小技巧就可以轻松的知道如何学习JS,首先大家要知道,JavaScript函数是可以使用任意数量的参数的。相较于其他语言(如C#和Java)不同,你是可以在调用JavaScript函数的同时,也能传递任意数量的参数。JavaScript的函数允许未知数量的函数参数。在ECMAScript 6之前,JavaScript有一个变量来访问这些未知或可变数目的参数,这是一个类似数组的对象,并非一个数组。细想以下代码来理解arguments变量:

function add(){

var result = 0;

for(let i=0;i<arguments.length;i++){

result = result + arguments[i];

}

return result;

}

var r = add(6,9,3,2);

console.log(r);

var t = add(7,56,9);

console.log(t);如你所见,arguments对象用于访问未知或可变的函数参数。即使arguments使用length属性和方括号,它也不是一个真正的JavaScript数组。你不能对arguments对象使用其他JavaScript数组方法,如pop,push,slice等。在使用arguments时存在的一些问题是:

JavaScript函数arguments对象不是一个真正的JavaScript数组;因此,你不能使用其他数组方法,如pop,push,slice等。

在内部函数中访问外部函数的arguments对象是很困难的。要访问的话,你需要在变量中分配外部函数的arguments函数,然后在内部函数中使用它。

如果你想要使用arguments对象作为数组,那么你需要通过Aarry.prototype.slice手动转换。

ECMAScript 6引入了一个新功能,Rest参数,它表示一个未知数量的参数作为函数中的一个数组。它不仅将额外的参数表示为数组,还解决了arguments对象的许多问题。使用rest参数重写上面的add函数。

function add(...theArgs){

var result = 0;

for(let i=0;i<theArgs.length;i++){

result = result + theArgs[i];

}

return result;

}

var r = add(6,9,3,2);

console.log(r);

var t = add(7,56,9);

console.log(t);你可以将rest参数定义为?theArgs或? args。如果最后命名的函数参数以?(三个点)作为前缀,那么它将成为函数的rest参数。JavaScript函数的rest参数是纯JavaScript数组。在上面的代码中,?theArgs是函数add的rest参数,因为它是唯一的命名参数,且也以?(三个点)作为前缀。由于rest参数是JavaScript数组,所以你可以对rest参数theArgs执行诸如push,pop等操作,如下面的代码所示:

function add(...theArgs){

theArgs.push(10);

var result = 0;

for(let i=0;i<theArgs.length;i++){

result = result + theArgs[i];

}

var lastItem = theArgs.pop();

console.log(lastItem);

return result;

}JavaScript函数的rest参数也可以与其他参数一起工作。如果你不想在rest参数数组中包含特定参数的话,那么你可能需要在函数中使用其他命名参数。细想以下代码块:

function add(num1, num2, ...theArgs){

console.log(num1);

console.log(num2);

console.log(theArgs.length);

}

var r = add(6,9,3,2);

var t = add(7,56,9);对于第一次函数调用,6和9将分别分配给num1和num2。对于第二个函数调用,7和56将被分配给num1和num2。启动第三个参数的参数将被分配给rest参数数组。请记住,前两个参数不会成为rest参数数组的一部分。所以,如果你打算将所有的值都包含在rest参数中,那么你应该一开始就将它们定义为用逗号分隔的命名参数。下面给出的代码将会导致错误:

function add(num1, ...theArgs,num2){

console.log(num1);

console.log(num2);

console.log(theArgs.length);

}在上面的代码中,rest参数不是最后一个参数,所以JavaScript会抛出错误。rest参数必须是最后一个正式参数。

JavaScript允许你破坏rest参数,这意味着你可以将rest变量数据解包为不同的变量名称。请看下面的代码:

function add(...[a,b,c]){

return a+b+c;

}

var r = add(6);

console.log(r);

var t = add(7,56,9);

console.log(t);第一次函数调用,将分配a = 6,b = undefined,c = undefined,第二次函数调用,将分配a = 7,b = 56,c = 9。在此例子中,函数将忽略传递的任何额外的参数。

JavaScript函数的rest参数是对arguments对象使用函数未知参数的一个巨大改进。它是一个纯JavaScript数组;因此,你可以对它使用所有数组方法。你可以将rest变量数据解包到命名变量中。你可以给rest参数指定任何名称,这又是一个使用arguments关键字的重大改进。

javascript如何给事件处理函数传递参数

方法一:通过事件在html中的内联方式来传递参数(假定变量x是参数,下同):

<input type="button" value="点我" onclick="var x=123;test(x);"/>

<script>

function test(x){

   alert(x);

}

</script>

方法二:通过全局变量来传递参数:<input id="abc" type="button" value="点我"/>

<script>

var x=123;

window.onload=function(){

   document.getElementById("abc").onclick=function(){

      alert(x);

   }

}

</script>

方法三:通过对象的自定义属性来传递参数:

<input id="abc" type="button" value="点我"/>

<script>

window.onload=function(){

   var abc=document.getElementById("abc");

   abc.x=123;

   abc.onclick=function(){

      alert(this.x);

   }

}

</script>

方法四:利用闭包:<input id="abc" type="button" value="点我"/>

<script>

window.onload=function(){

   (function(x){

      document.getElementById("abc").onclick=function(){

         alert(x);

      }

   })(123);

}

</script>

暂时就想到这么多了,肯定还有其他方法的。

javascript中把函数作为参数传递给另一个函数的问题

x是形参。

var func=new Function("x","alert(x+10);")

相当于

var func = function (x) {

    alert(x + 10);

};

如果要添加变量y

var func = new Function('x', 'y', "alert(x + y + 10);");

/* 相当于

var func = function (x, y) {

    alert(x + y + 10);

};

然后call

function call(first, second, third) {

    first(second, third);

};

// call(func, 1, 2);

// x就是1,y就是2

javascript的函数function调用时参数个数必须匹配吗

因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java一样对其传入参数的类型进行定,也对传入参数的个数没有要求。

js函数的参数与大多数其他语言中的函数的参数有所不同。js函数不介意传递进来多少个参数,也不在乎穿进来参数是什么数据类型。也就是是说,即便你定义的函数值接受两个参数,在调用这个函数时也未必一定要是两个参数。可以传递一个、三个甚至不传递参数,而解析器永远不会有什么怨言。之所以会这样,原因是js中的参数在内部是用一个数组来运行的。函数接受到的永远是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没问题。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给含糊的每一个参数。

javascript的函数function调用时参数个数必须匹配吗

因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java一样对其传入参数的类型进行定,也对传入参数的个数没有要求。

js函数的参数与大多数其他语言中的函数的参数有所不同。js函数不介意传递进来多少个参数,也不在乎穿进来参数是什么数据类型。也就是是说,即便你定义的函数值接受两个参数,在调用这个函数时也未必一定要是两个参数。可以传递一个、三个甚至不传递参数,而解析器永远不会有什么怨言。之所以会这样,原因是js中的参数在内部是用一个数组来运行的。函数接受到的永远是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没问题。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给含糊的每一个参数。

eval()函数的原理是什么?

eval() 函数作用是可以接受一个字符串str作为参数,并把这个参数作为脚本代码来执行。

如果参数是一个表达式,eval() 函数将执行表达式; 如果参数是Javascript语句,eval()将执行 Javascript 语句。(如果执行结果是一个值就返回,不是就返回undefined,如果参数不是一个字符串,则直接返回该参数)。

eval()函数并不会创建一个新的作用域,并且它的作用域就是它所在的作用域,有时候需要将eval()函数的作用域设置为全局,当然可以将eval()在全局作用域中使用,这个时候可以用window.eval()的方式实现。

eval() 函数案例

eval("var a=1");//声明一个变量a并赋值1。

eval("2+3");//执行加运算,并返回运算值。

eval("mytest()");//执行mytest()函数。

eval("{b:2}");//声明一个对象。如果想返回此对象,则需要在对象外面再嵌套一层小括如下:eval("({b:2})"); 

注意:使用eval来解析JSON格式字符串的时候,会将{}解析为代码块,而不是对象的字面量量

//1.在JSON格式的字符串前面拼接上 "var o ="

//2.把JSON格式的字符串使用()括起来,就不会将{}解析为代码块,而是表达式

JavaScript 函数参数传递问题?

1 同样都是值传递为什么可以给对象加属性?

当参数为对象是,就不只是值传递而是引用传递了。所以楞以通过obj.name改变原对象的属性。

2 还有后面的var obj是把前一个obj覆盖了吗?

是的,当你再次var obj=new Object()的时候,会让js引擎将obj作为一个新的变量,参数obj在后面的代码中已经无效了。

3 左边错误没有输出。右边正常,变量声明放在使用的后面只有值类型的变量可以吗?

在js中,变量的声明永远都需要放在变量使用前,右边的结果参见上面2的说明。左边出错,是因为在执行到kk.name = 5的时候,会先检查变量kk是否存在,若不存在,当然不能调用它的name属性了,所以后面的代码都不会再执行。而在右边,kk=5相当于var kk = 5;所以可以在后面使用alert(kk)输出,但是再后面的代码 var kk 则会覆盖前面的kk变量(也就是说kk不再是5,而是一个新的变量了)。追问2,3能懂了,可1,JavaScript高级程序设计里说ECMAScript中所有的函数参数都是按值传递的啊。不过它还说就算是按值传递的,obj也会按引用来访问一个对象。可不可以按c语言的指针来理解,把指针的值也就是保存的地址传给函数,然后函数里的obj使用时就是引用内存里的那个地址,后面重新声明的话,就使obj指向后面objec的地址了?

追答是这样理解的。

欧尚宠物网还为您提供以下相关内容希望对您有帮助:

js中函数的参数为对象时候怎么操作

javascript函数中的参数对象arguments是个对象,而不是数组。但它可以类似数组那样通过数字下表访问其中的元素,而且它也有length属性标识它的元素的个数。通常我们把它转换成数组用array的slice函数,示例代码如下:function fn()...

javascript中把函数作为参数传递给另一个函数的问题

x是形参。var func=new Function("x","alert(x+10);")相当于 var func = function (x) { alert(x + 10);};如果要添加变量y var func = new Function('x', 'y', "alert(x + y + 10);");/* 相...

...触发一个函数,如何将该元素的对象作为函数的参数传过去

--把元素对象作为参数传进js函数里--&gt;我是div元素 public void onShowPromptDialog1(View v){ //inflate需要显示到Dialog里的View对象 LayoutInflater li = LayoutInflater.from(this); View view = li.inflate(R...

JavaScript:将函数作为参数传入,作为回调函数

function doSomething(args,callback){ somethingComplicated(args); callback();}//第一个参数如果不需要传递,可设置为null//function onEnd(){} 这种方法通常是声明一个函数, 将函数作为参数传递可直接传递函数名称...

javascript如何给事件处理函数传递参数

方法一:通过事件在html中的内联方式来传递参数(假定变量x是参数,下同):function test(x){ alert(x);}方法二:通过全局变量来传递参数:var x=123;window.onload=function(){ document.getElementById("abc")....

javascript函数传参问题

我个人偏向于的观点是:如果参数是js基本数据类型,那么就是按值传递;如果是引用类型如对象、数组、函数,那么就是按引用传递。用这个观点去解释你的例子,应该是没有矛盾的地方的。①处按照js对象的比较运算规则,只有全等...

JavaScript 函数参数传递问题?

1 同样都是值传递为什么可以给对象加属性?当参数为对象是,就不只是值传递而是引用传递了。所以楞以通过obj.name改变原对象的属性。2 还有后面的var obj是把前一个obj覆盖了吗?是的,当你再次var obj=new Object()的...

c++中对象可以作为函数参数吗

类的对象、结构体的对象 都是可以作为函数的参数的。struct tagStu{string m_strName;string m_strSex;}class CManage{void SetStu(tagStu stu){ // 结构体m_tagStu.m_strName = stu.m_strName;m_tagStu.m_str...

C++中对象作为函数参数传递的问题

1.首先要明确void display(people x){...}是传值方式传参,实参要向形参复制对象,在复制对象时会调用拷贝构造函数。2.由于people类中没有显式定义拷贝构造函数,将使用默认拷贝构造函数不会自动复制堆资源(即通过new得到...

JavaScript中怎样点击超链接后执行一个函数并且把超链接的文本作为函数...

具体HTML代码:538路代码解释:onclick是对a标签进行点击事件绑定。chaXunCheCi是原来的函数。this.innerHTML得到链接文字。注意,如果链接中不是纯文本,而是有其他元素,建议改为this.innerText稳妥一些。

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

Top