文章配套视频
函数使用注意
1. 在调用函数时,可以在()中指定实参, 实参将会赋值给函数中对应的形参
2. 调用函数时解析器不会检查实参的类型, 所以开发中一般需要对参数进行类型的检查
3. 函数的实参可以是任意的数据类型
4. 调用函数时,解析器不会检查实参的数量, 多余实参不会被赋值,
如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
arguments对象
包含了传入函数中的所有参数, arguments并不是一个数组,
只是与数组相似, 除了拥有length属性,
数组的所有属性和方法都不具备。
arguments对象还有一个名叫callee的属性,
该属性是一个指针, 指向拥有这个arguments对象的函数;
length属性
函数形参的个数
函数返回值(return)
1)当一个函数被调用,通常会从函数的开始执行到结束。
2)如果想提前结束该函数的执行可以使用return语句,return语句后面的所有语句将永远不会执行。
3)一般return用于返回结果。
4)注意
如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined
如果函数使用 return语句,那么跟再return后面的值,就成了函数的返回值
如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。
函数直接声明和函数表达式声明的区别
JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面
// 代码没问题
console.log(f(5,6));
function f(a, b) {
return a + b;
}
// 报错
myFun(6,7);
var myFun = function (a,b){
return a + b;
}
匿名函数
没有命名的函数:function () {}
作用:
用在绑定事件的时候
document.onclick = function () {
alert(1);
}
定时器
setInterval(function () {
console.log(444);
},1000);
立即执行函数
1)函数定义完,立即被调用,这种函数叫做立即执行函数
2)立即执行函数往往只会执行一次
3)(function(){alert("hello")})();
4)(function(num1, num2){
console.log("mum1 = "+ num1);
console.log("num2 = "+ num2);
})(100, 101);
函数是一种数据类型
console.log(typeof fn);
console.log(typeof fn());
归根结底,它还是属于object
回调函数
1)回调函数就是一个通过函数调用的函数。
2)如果你把函数的指针(地址)作为参数传递给另一个函数,
当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
3)一般用于递归
4)经典案例
求Fibonacci的第n个数
1 1 2 3 5 8 13 21...
function f1 (n) {
if (n == 1) return 1;
if (n == 2) return 1;
return f1(n-1) + f1(n-2);
}
console.log(f1(7));
求n个数的累加
function getSum (n) {
if (n == 1) { return 1;}
return n + getSum(n - 1);
}
console.log(getSum(100));
从前有座山,山里有座庙, .....
var i = 100;
function f1 () {
i--;
//递归的结束条件
if (i >= 0) {
console.log("从前有座山,山上有座庙" + i);
//递归调用
f1();
}
}
f1();
变量的作用域
块级作用域
在其它语言中,任何一对花括号中的语句都属于一个块,在这之中定义的所有变量在代码块外都是不可见的
全局变量
定义在script或者不属于某个函数的变量
局部变量
定义在函数内部的变量
注意:
函数内部可以访问到该函数所属的外部作用域的变量(作用域链)
不使用var声明的变量是全局变量,不推荐使用(XXXX)
变量退出作用域之后会销毁,全局变量关闭网页或浏览器才会销毁
作用域链相关
题目1:
{
var num = 5;
}
console.log(num);
题目2:
var num = 5;
if (num > 3) {
var sum = 7;
}
console.log(sum);
其它语言中变量i只能在for循环内部访问(局部变量)
for (var i = 0; i < 10; i++) {
}
console.log(i);
全局变量:
var name = "旋之华";
function f() {
name = "刘德华";
}
f();
console.log(name);
局部变量, 先在函数内部的作用域找变量name,如果找到则使用,如果找不到去父级作用域找name变量
function f() {
var name = "撩课学院";
}
f();
console.log(name);
作用域链:
var color = "yellow";
function getColor() {
var anotherColor = red";
function swapColor() {
var tmpColor = color;
color = anotherColor;
anotherColor = tmpColor;
}
swapColor();
}
getColor();
console.log(color);
变量提升
变量提升:
定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升。
函数提升:
JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面
面试相关
var num = 10;
fun();
function fun(){
console.log(num);
var num = 20;
}
var a = 18;
f1();
function f1(){
var b=9;
console.log(a);
console.log(b);
var a = '123';
}
f1();
console.log(c);
console.log(b);
console.log(a);
function f1(){
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}