函数与返回值
function fn(n,m){//=>形参:入口
//函数体
var total =0; //=>total是私有变量
total = n+m;
console.log(total);
}
fn(10,20) ; //=>实参:给形参传递的具体值
var a=12;
fn(a,1===1?10:0);//实参一定是值,即使我们写的是变量或者表达式,也是把变量或者表达式计算的结果作为值传递给形参变量
创建函数,开辟一个堆内存空间,把函数体代码当作字符串存进来,把堆内存的地址复制给函数名
function fn(n,m){ //=>形参:入口 //函数体 var total =0; //=>total是私有变量 total = n+m; } fn(10,20) ; console.log(total); => VM55:8 Uncaught ReferenceError: total is not defined //total 是私有变量,我们无法在函数的外面直接获取这个值(闭包)
fn是函数体,函数本身
fn( )代表的是函数执行的值,就是return返回的值
/*
* 函数的入口:形参
* 函数的出口:返回值return
* 把函数运行的结果(或者函数体中的部分信息)拿到函数外面去使用
*/
function fn(n,m){
var total =0; //=>total是私有变量
total = n+m;
return total; //=>并不是把total变量返回,而是返回的是变量存储的值,return返回的永远是个值
}
=>console.log(fn(1,2));
VM344:1 3
相当于:
var result = fn(1,2);
console.log(result);
如果当前函数没有return结果出来(或者return;啥也没有返回)函数执行在外面拿到的结果都是undefined
return还有一个重要的作用:
function fn(n,m){
var total=0;
total=n+m;
return total;
}
console.log(fn(10));
=>NaN //n为10,m为undefined
//如果n/m有一个没有传递值,我们返回零
需求如果n/m有一个没有传递值,我们返回零
function fn(n,m){
if (n === undefined || m === undefined) {
return 0;
//return 还有一个作用:类似循环中的bank,能够强制结果函数体中的代码执行
}
var total=0;
total=n+m;
return total;
}
console.log(fn(10));
=>0 //n为10,m为0
//如果n/m有一个没有传递值,我们返回零
//n === undefined 经常这样判断n的值是否为undefined,这种方式可以
//n == undefined 这种模式不好,因为null == undefined 也是相等的(==比较才不相等)
//type n == 'undefined' 真实项目中开发者更喜欢这种判断方式
total=0; 0是有值的,值为0,从内存方面来说,undefinedye会在栈内存中占一个位置 total=null; 开发者更喜欢用null来作为初始值,null是空对象指针,是不占内存位置的
/*
- 任意数求和:不管函数执行的时候,传递多少实参进来,我们都可以求和
- 形参有局限性:我们需要具体的知道用户执行的时候传递实参数量,顺序等,才可以使用形参变量定义对应的入口
arguments及求和
- arguments :函数内置实参的集合(内置:函数天生存在的机制,始终存在,不管是设置了实参,还是传递了实参) */
function sum(n,m,z){
console.log(argument);
/*
* arg是一个类数组(不是数组,不能直接使用数组中的方法)
* 即使设置形参变量,形参该是什么,还是什么值,但是arg使用存储的是所有传递进来的实参,所有叫实参集合
*/
}
sum(10,20)
=>M52:2 Arguments(2) [10, 20, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 10
1: 20
callee: ƒ sum(n,m,z) //存储的是当前函数本身
length: 2
/*
* 把arg中存储的实参依次遍历,每遍历一个都累加起来,最后实现任意数求和
*/
function sum(){
var total = null;
for (var i=0;i<arguments.length; i++){
var item = arguments[i]; //每一次遍历出来的实参值
total += item;
}
return total;
}
console.log(sum(10,20,30));
-> argument的callee的属性
function sum(n,m){
console.log(arguments.callee===sum);
}
sum(10,20);
=>VM373:2 true
function sum(n,m){
console.log(arguments.callee);
}
sum(10,20);
=>VM434:2 ƒ sum(n,m){
console.log(arguments.callee);
}
undefined
实现任意数求和方法1
/*
* 把arg中存储的实参依次遍历,每遍历一个都累加起来,最后实现任意数求和
*/
function sum(){
var total = null;
for (var i=0;i<arguments.length; i++){
var item = arguments[i]; //每一次遍历出来的实参值
total += item;
}
return total;
}
console.log(sum(10,20,30));
=>60
//如果传递字符串
console.log(sum(10,'20')) =>'1020'
实现任意数求和方法2
/*
* 把arg中存储的实参依次遍历,每遍历一个都累加起来,最后实现任意数求和
* 如果传递字符串,把字符串转为数字,然后累加
*/
function sum(){
var total = null;
for (var i=0;i<arguments.length; i++){
var item = arguments[i]; //每一次遍历出来的实参值
//1.不管item获取的事传递的啥,都先转换为数字类型 sum(10,'20','AA')
item = Number(item);
//2.如果当前的值是有效数字我们才累加,非有效数字直接跳过即可
isNaN(item)?null:total += item;
}
return total;
}
//如果传递字符串,把字符串转为数字,然后累加
console.log(sum(10,'20','AA')) =>30
用es6实现
let sum=(...arg) => {
arg = arg.filter(item => !isNaN(item));
return eval(arg.join('+'));
};
console.log(sum(10,'20','AA'));
=>30
实名函数:有函数名 匿名函数:没有函数名
- 函数表达式: 把函数当做值赋值给变量或者元素的事件
- 自执行函数:创建和执行一起完成的
//函数表达式
var fn = function () {
}
//匿名函数
oBox.onclick = function () {
}
//自执行函数
(function () {
})();
~function (){
}();
+function (){
}();
!function () {
}();