目录
函数的返回值return
返回值的类型
break、continue、return、 throw new Error()的区别
arguments
例一
例二
面试题:
函数的方法
面试题:call()、apply()、bind()的区别
函数调用函数
立即执行函数
数据的存储
简单类型与复杂类型
堆和栈
函数的返回值return
function 函数名(){
return 需要返回的结果
}
函数名()
现在创建一个函数,用来计算三个数的和sum,平均数avg
function getSum(a, b, c) {
let sum = a + b + c;
let avg = (a + b + c) / 3;
// return sum, avg;//return只返回一个值,多个值返回最后一个,同时return具有终止语句的作用,后面语句不再执行
return { sum, avg }; //return返回多个值可以放在对象或者数组里(一个集合)
// return [sum, avg];//数组
}
let res = getSum(1, 2, 3);
console.log(res);
函数只是实现某种功能,最终的结果需要返回给函数的调用者(谁调用函数,函数实现结果功能反馈给谁),函数名()=return 后面的结果,通过return实现的;可以定义一个变量,让return来接受该结果
在函数中,return之后的语句就都不会执行,有终止函数的作用
return只能返回一个值,多个值,返回的是最后一个值。如果有需求返回多个值,可以将多个值放入数组或者对象里
return后可以跟任意类型的值
如果return后不跟任何值,就相当于返回一个undefined
如果函数中不写return,则也会返回undefined
返回值的类型
返回值可以是任意的数据类型, 也可以是一个对象 ,函数
//返回值是对象
let fun1 = function (age) {
let obj = {
name: "张三",
age
};
return obj;
}
console.log(fun1(18));
//返回值是函数
let fun2 = function () {
console.log("我是外层函数");
let fun3 = function () {
console.log(111);
return "我是内层函数的返回值";
}
return fun3;//将函数fun3作为返回值返会
}
console.log(fun2()());//闭包写法
break、continue、return、 throw new Error()的区别
break; //退出当前的循环
continue;//用于跳过当次循环
return;//使用return可以结束整个函数
throw new Error("出错了,终止代码");//抛出异常,函数立即终止,后续代码不执行
function fun() {
alert("函数要执行了~~~");
for (var i = 0; i < 5; i++) {
if (i == 2) {
// break; //退出当前的循环
// continue;//用于跳过当次循环
// return;//使用return可以结束整个函数,下面都不执行
// 抛出异常,函数立即终止,后续代码不执行
throw new Error("出错了,终止代码");
}
console.log(i);
}
alert("函数执行完了~~~");
}
fun();
arguments
在调用函数时,浏览器每次都会传递两个隐含的参数:
1:函数的上下文对象 this
2:封装实参的对象 arguments
当我们不确定有多少个参数传递的时候,可以使用arguments来获取,在JS中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
(1)、arguments 是一个类(伪)数组对象
它可以通过索引来操作数据,通过arguments.length可以获取实参的长度
伪数组并不是真正意义上的数组
具有数组的length属性
按照索引的顺序进行存储的
它没有真正数组的一些方法
(2)、在调用函数时,我们所传递的实参都会在arguments中保存
(3)、我们即使不定义形参,也可以通过arguments来使用实参,只不过比较麻烦
arguments[0]表示第一个实参
arguments[1]表示第二个实参
(4)、arguments有个属性叫callee,
这个属性对应一个函数对象,就是当前正在指向函数的对象
例一
封装函数,求任意个数的最大值,使用arguments索引,获取到对应的属性值
function getMax() {
for (let i in arguments) { //输出索引,我输入四个值,所以这里输出0、1、2、3
console.log(i);
}
let max = arguments[0];
// console.log(arguments.length);
for (let i = 0; i < arguments.length; i++) {
if (max < arguments[i]) {
max = arguments[i];
}
}
return max;
}
let res = getMax(100, 200, 300, 1000);
console.log(res);
例二
使用arguments.callee来调用自己,实现递归调用
//这里来计算匿名函数的阶乘(如果给函数命名就可以直接递归调用)
let fun1 = (function (n) {
if (n – 1 == 0) {
return 1;
}
return (n * arguments.callee(n – 1))
})(5);
// fun1();此时fun1被赋值为120是个数字无法当成函数调用
console.log(fun1);
面试题:
1、伪数组跟真数组的区别?
伪数组并不是真正意义上的数组
具有数组的length属性
按照索引的顺序进行存储的
它没有真正数组的一些方法
2、如何获取到伪数组?
第一种方式:arguments
第二种方式:dom获取多个标签时,拿到就是伪数组
函数的方法
call()、apply()、bind()
面试题:call()、apply()、bind()的区别
这三个方法都是函数对象的方法,需要通过函数对象来调用
当对函数调用call()和apply()方法时,都会调用函数执行,当函数调用bind()方式,会返回当前函数,需要手动调用
在调用call和apply(),bind()可以将一个对象指定为第一个参数, 此时这个对象将会成为函数执行中的this
call()、bind()方法传递函数的其他参数,需要一个个传,apply()方法需要将实参封装到一个数组中统一传递
call(指定this是谁,实参1,实参2,·····)
apply(指定this是谁,[参数1,参数2,·····])
bind(指定this是谁)(参数1,参数2,·····)
函数调用函数
每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况
一般情况下,一个函数只做一件事
例题:用户输入年份,告知当年2月份多少天
function getDays() {
var year = prompt("请输入年份");
if (isRunYear(year)) {
alert("闰年2月有29天");
} else {
alert("平年2月有28天");
}
console.log(isRunYear(year));
}
getDays();
function isRunYear(year) {
var flag = false;
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
flag = true;
}
return flag;
}
立即执行函数
语法结构:函数对象()
立即执行函数,函数定义完后,立即被调用,立即调用函数,往往只会执行一次
//第一种写法
(function(){
alert("我是一个匿名函数~~~");
})();//外面的()是把整个函数当作函数名,后面的()是调用函数的意思
//第二种写法
(function () {
alert('匿名函数执行方式二')
}());
//匿名函数传参
(function(a,b){
console.log("a="+a);
console.log("b="+b);
})(123,456);//不仅可以调用,还可以传值
数据的存储
简单类型与复杂类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型
值类型:简单数据类型/基本数据类型,在存储时变量中存储的时值本身,因此叫做值类型
string、number、boolean、undefined、null
注意:简单数据类型 null 返回的是一个空的对象 object
如果有个变量我们以后打算存储为对象,暂时没想好放啥,就可以给null
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型,通过new关键字创建的对象(系统对象、自定义对象),如Obect、Array、Date等
堆和栈
堆栈空间分配区别:
栈(操作系统):简单数据类型存放在栈里面,里面直接开辟一个空间存放的是值
堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
复杂数据类型存放在堆里面,它是先是在栈里面存放地址,十六进制表示,然后这个地址指向堆里面的数据
总结:
1、JS中的变量都是保存到栈内存里的
2、基本数据类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响其他的变量
3、引用数据类型的值直接保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当通过一个变量修改属性时,另一个也会受到影响
4、比较两个基本属性类型的值时,就是比较值;
比较两个引用数据类型时,它是比较对象的内存地址,如果两个对象时一模一样的,但是地址不同,他也会返回false


