您的位置:首页 > Web前端 > JavaScript

【JavaScript学习笔记】5:有关函数,typeof,参数过多/不足,arguments,rest

2018-02-07 17:17 941 查看

通过字面量赋值定义函数

除了传统的定义方式,还可以用字面量赋值的方式来定义一个函数,然后用一个变量为函数名去调用那个匿名函数。

但是这种定义函数的方式和传统的定义方式并不等价,廖老师教程里说完全等价是不对的!这种定义方式要求函数定义必须在使用之前,而传统的定义方式则不需要:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
var myfun=function(x,y){
return x+y;
}; //注意分号
ok=myfun("牛逼","啊!");
console.log(ok);
</script>
</HEAD>
</HTML>


输出

牛逼啊!


试想变量还没声明,哪里能以这个变量为名调用函数呢。

通过Function()构造器定义函数

用new关键字带Function()构造器的方式可以去定义一个函数:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
var myfun=new Function('x','y','return x+y');
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

7


typeof关键字

js中的typeof关键字可以用来检测变量的数据类型,注意Array是一种特殊的Object,所以对一个Array用typeof得到的是”object”:

x=new Array();
[]
typeof x;
"object"


可以看到typeof得到的是一个字符串,里面是数据类型的名称。

现在可以验证一下只有一种数字类型:

typeof 3.14;
"number"
typeof 3;
"number"


此外,null和undefined都可以用来清空对象,但是它们用typeof得到的数据类型是不一样的:

x=null;
null
typeof x;
"object"
x=undefined;
undefined
typeof x;
"undefined"


而NaN实际上是一个数字类型,这有些不可思议(表示不是数字的量竟然是一个数字量):

typeof NaN;
"number"


Infinity是一个数字类型是自然的:

typeof Infinity;
"number"


函数也有类型,是function类型的:

x=Function("x","y","return x+y");
anonymous(x,y
/**/) {
return x+y
}
typeof x;
"function"


参数过多和参数不足

基本情况

函数的参数太多时,只会取用前几个需要的参数,无视后面的参数;函数的参数不足时,往往而不是一定返回NaN:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
var myfun=new Function('x','y','z','return x+y+z');
console.log(myfun(3,4,5,6));
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

12
NaN


undefined缺失值

参数不足时,没有收到实参的那些形参就是undefined,如果使用了它进行了返回值的计算,结果自然是NaN(无法计算):

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
var myfun=function (x,y,z){
console.log(x,y,z);
console.log(x+y+z);
return x+y+z;
};
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

3 4 undefined
NaN
NaN


缺失者多余的情况

如果函数里根本没有用到缺的参数呢?那么函数完全可以正常返回:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
var myfun=function (x,y,z){
if(typeof x==="number")
return x+y;
else
return x+y+z;
};
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

7


可能带来的问题

如果这个缺失值产生的undefined能让函数正常跑,对于复杂的逻辑这个结果可能没法预知(我认为这是js的缺点):

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
var myfun=function (x,y,z){
if(z===0)
return x-y;
else
return x+y;
};
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

7


看起来好像代码没问题一样。

arguments关键字

基本用法

在函数内,arguments关键字始终携带传入的所有参数:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
"use strict";
var myfun=function (x,y,z){
//console.log(type arguments); //只是一个关键字,没有类型
console.log(arguments); //可以直接输出它看一下
//很像数组∈object,用增强for遍历出的只是"键"
for(let i in arguments){
console.log(i+"->"+arguments[i]);
}
};
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

[3, 4]
0->3
1->4
undefined


arguments是一个关键字,不是变量,没法用typeof取得其类型。其外在表现非常像一个数组(但不是!),刚学了数组属于object对象,可以对其迭代取出其中的值。

就如对object进行增强for时是在遍历它的键一样,对数组进行增强for也是在遍历它的下标,也就是说,数组作为特殊的object应当被视为下标:元素值的键值对系

可能存在的风险

arguments并不是写保护的,可以被赋值,但这样就破坏了其意义:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
"use strict";
var myfun=function (x,y,z){
console.log(arguments); //先输出一下
//对arguments赋值
for(let i in arguments){
arguments[i]=arguments[i]+1;
}
console.log(arguments); //再输出一下
};
console.log(myfun(3,4));
</script>
</HEAD>
</HTML>


输出

[3, 4]
[4, 5]
undefined


rest参数

在ES6标准下提供了rest参数,其用法很像python的可变长度参数。rest参数用来获取后面那些多余的参数:

<!DOCTYPE HTML>
<HTML>
<BODY>
</BODY>
<HEAD>
<meta charset="utf-8">
<script>
//rest参数只能放在参数表的最后,且前面要用三个'.'表示其是变长的
function myfun(x,y,z,...rest){
console.log(typeof rest); //输出其类型看一下
console.log(rest); //输出rest参数看一下
return x+y+z;
}
console.log(myfun(3,4,5,6,"牛逼",[1,2,3])); //提供的参数多了
</script>
</HEAD>
</HTML>


输出

(我的老chrome长年不更新已经不支持,在火狐下试一下)

object
Array [ 6, "牛逼", […] ]
12




实际上这个参数不一定真的要写成rest,写成别的合法不冲突的变量名也是一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: