前言
本文从函数定义,函数参数、返回值、函数内部对象及箭头函数方面对函数进行深入了解。
一、函数定义
函数是javascript中重要的组件之一,函数是把一段拥有重复功能的代码语句封装起来,形成一个独立实体,实现某些特定的功能。
每个函数都是Function类型的实例,函数也是对象,函数名就是指向函数的指针。
1.函数定义
函数一般通过函数声明、函数表达式和Function构造函数三种方式实现。
函数声明示例
<script>
/*
*函数声明
* 函数名是getName,指向函数对象的指针
* }向左括号后不需要加;号,因函数声明不是一个可执行语句
*
*/
function getName(name){
console.log(name+" 看csdn");
}
console.log(getName);//输出函数声明体内容
getName("marshal");//执行函数
</script>
函数表达式示例
<script>
/*
*函数表达式
* 将函数表达式存储在变量getName中,变量getName可作为函数一样使用
*}向左括号后可加;号,因是一个可执行语句
*
* 函数表达式与函数声明几乎是等价,区别在于使用函数声明,将会声明提前,后面会提到
*/
var getName=function(name){
console.log(name+" 看csdn");
};
console.log(getName);//输出函数声明体内容
getName("marshal");//执行函数
</script>
Function构造函数示例
<script>
/*
*Function构造函数
* 构造函数可以接收多个参数,最后一个参数是函数体,之前的全为形参
*不推荐采用Function构造函数来定义
* 原因new Function 代码会被解释两次
* 第一次是当用常规ECMAScript 代码
* 第二次是解释传给构造函数的字符串,影响性能
*
*/
var getName=new Function("name","csdn","return name+csdn");
console.log(getName);//输出函数内容
console.log(getName("marshal","csdn"));//执行函数,输出marshalcsdn
</script>
2.函数参数
形参与实参
在函数定义过程中,可以在函数的()内指定多个参数,函数()内指定的参数统一称为形参(形式参数),类似占位符,先用一个标识代替。
<script>
/*
* 函数名称getBookPrice,num,price 为函数参数的形参
* getBookPrice(10,55) 10,55 为传入的实参(实际参数)
*
*/
function getBookPrice(num,price){
return num*price;
}
var totalPrice=getBookPrice(10,55);
console.log(totalPrice);//550
</script>
Arguments 对象理解
ECMAScript函数的参数与其他语言如java,c#等不一样,在javascript中,函数不存在重载说法,函数名称相同的,永远是最后一个函数定义会覆盖之前的重命名函数。这意味着函数定义时比如是两个参数,在调用传实参时,可以传一个或两个以上的参数进行传递,js解释器也不会报错。
这是由于函数的参数在内部是一个数组,函数被调用时总是会接收一个数组,函数内部隐藏了一个arguments对象,我们可以通过arguments获取参数的值。
<script>
/*
*
* 在调用函数时,函数内部隐藏了arguments对象
* arguments[0]=10
* arguments[0]=55
*/
function getBookPrice(){
console.log(arguments.length);//输出2
return arguments[0]*arguments[1];
}
var totalPrice=getBookPrice(10,55);
console.log(totalPrice);//550
</script>
默认参数值
<script>
/*
*默认参数值在函数参数赋默认值
* arguments 只对传给函数的参数有效,对默认参数值无效
*
*/
function getBookName(name='javascript',price=100){
console.log(arguments.length); //0
return "name:"+name+",price:"+price
}
console.log(getBookName()); //输出 name:javascript,price:100
</script>
<script>
/*暂时性死区说明
*默认参数值在函数参数赋默认值
*后一个参数的默认值可以为前面定义的参数
*前面定义参数的值,为不能后面的定义参数
* 原因:参数是按顺序初始化,该过程与let 声明变量类似
* 参数初始顺序遵循“暂时性死区”规则,前面定义的参数引用后面的则抛出错误
*/
function getBookName(name='javascript',price=name+100){
return "name:"+name+",price:"+price
}
console.log(getBookName()); //输出 name:javascript,price:100
</script>
3.函数返回值
Javascript函数可以返回任意类型的值。
<script>
function add(num1,num2){
return num1+num2;
}
console.log(add(100,200));//输出300
console.log(add("bookName","javascript"));//输出 bookNamejavascript
console.log(add(true,false));//输出1
function obj(name,price){
return {"name":name,"price":price};//返回对象
}
var o=obj("javascript","100");
console.log(o.name,o.price); //输出javascript 100
</script>
4.函数特殊对象arguments与this
在参数那一小节已说的arguments是函数的隐藏对象,可以获取传递参数的值及数量,是一个伪数组。在这不再多说,接下来阐述下this使用。
<script>
/*
*
* this 是函数内部传递的一个参数,this指向一个对象
* 每调用一次生成一个新的this
* 函数形式调用,this 为window
* 方法形式调用,this为方法的对象
* 使用call,apply可以改变this的对象
*/
function getName(){
console.log(this);
}
getName();//函数形式调用 输出 window
getName();//函数形式调用 输出 window
let obj={
bookName:'javascript',
getBookName:getName
}
let obj2={
bookName:'java',
getBookName:getName
}
obj.getBookName();//方法形式调用 输出 obj
obj.getBookName.call(obj2); //call 输出 obj2
obj.getBookName.apply(obj2); //apply 输出 obj2
</script>
5.箭头函数
ECMAScript 6新增了使用胖箭头(=>)语法定义函数表达式的能力。箭头函数与函数表达式创建的函数对象行为是相同的,两者可以替换。
箭头函数示例
<script>
/*
*箭头函数
* 只有一个参数时,()可以省去,没有参数或大于一个参数时,()必需要有
* 箭头后面大括号建议保留,说明是函数体
* 箭头不能使用arguments,super,new.target
* 箭头函数的this,引用的是定义箭头函数的上下文
* 标准函数的this,引用的是把函数当成方法调用的上下文
*/
let priceTotal=(num,price)=>{
return num*price;
};
console.log(priceTotal(10,100));
let priceTotal=()=>{return 10;}; //语法正确
let priceTotal=price=>{return price;}; //语法正确
let priceTotal=num,price=>{
return num*price; //语法错误,不能省去()
};
</script>