这是坚持学习的第二天,虽然没什么值得骄傲的,但终归是个好的开始不是么!今天依旧会把学到的东西做个记录总结,一方面方便自己以后复习,或是需要的时候方便查阅,另一方面希望与同在学习js的朋友们互通有无。如果你恰好在学js,又恰好看到了我的文章,请务必留个言好让我知道你我如此有缘。
js函数声明
JavaScript 函数是通过 function 关键词定义的,例如:
function functionName(parameters) {
要执行的代码
}
functionName表示函数名
parameters表示函数的参数,参数可以根据需求定义一个或多个
函数体需要放置在大括号内,这与大多数语言相似
由于函数声明不是可执行的语句,故一般无需在 } 后加;结尾
JavaScript 默认将变量声明和函数声明移动到当前作用域顶端,所以JavaScript 函数能够在声明之前被调用
myFunction(5);
function myFunction(y) {
return y * y;
}
js函数变量
在js中函数声明可以保存在变量中使其可以直接调用函数
函数声明赋值给变量的方式有两种:
1.直接将定义好的函数赋值给变量,例如:
function sum(a,b) {
return a+b;
}
var tempsum = sum;
var total = tempsum(5,6);
2.在变量赋值时定义函数,例如:
var tempsum = function (a,b) {return a+b;};
var total = tempsum(5,6);
大家可能注意到了在变量赋值时定义函数是没有函数名的,这样定义的函数为匿名函数,总是使用变量名调用。即使在定义中加上函数名也不能使用函数名调用。
typeof 运算符会为函数返回 “function”。
js函数调用
函数在调用时,函数内部的代码块会被执行。
函数的调用方式有如下几种
1.以函数形式调用函数,例如:
function myFunction(a, b) {
return a * b;
}
myFunction(10, 2);
2.作为函数构造器来调用函数,例如:
function myFunction(arg1, arg2) {
this.firstName = arg1;
this.lastName = arg2;
}
// 创建了一个新对象:
var x = new myFunction("Bill", "Gates");
x.firstName; // 会返回 "Bill"
作为构造器调用会创建新对象。新对象会从其构造器继承属性和方法。
js函数参数和返回值
函数参数包括两个部分,函数声明时的参数名称,和函数调用时接收到的真实值,调用时接收到的真实值会被存储在函数的内置参数数组arguments中。
JavaScript 函数定义不会为参数规定数据类型
JavaScript 函数不会对参数值进行任何检查,包括数量和类型
如果调用参数时省略了参数(少于被声明的数量),则被省略的参数设置为:undefined。
如果你在函数声明时不能确定参数的数量,可以使用函数的内置参数数组arguments来获取调用时实际接收到的参数,例如以下实现获取参数中的最大值:
x = findMax(1, 123, 500, 115, 44, 88);
function findMax() {
var i;
var max = -Infinity;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
JavaScript 参数传递分为两种
1.值传递:函数只知道值,而不是参数的位置。如果函数改变了参数的值,它不会改变参数的原始值
2.引用传递:会改变传入对象的原始值
一般来说变量使用值传递,对象使用引用传递。
js自调函数
自调函数首先是匿名函数,即你无法通过函数名来调用。自调函数也不允许使用参数
自调函数在声明的时候就会调用自身
自调函数实现举例:
(function () {
document.getElementById("demo").innerHTML = "Hello! I called myself";
})();
js 嵌套函数
嵌套函数是在其函数内部声明函数的一种函数用法。
其内部声明的函数可以使用在其内部声明的所有变量,例如:
function add() {
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
内部函数的调用通常分为两种:
1. 内部调用
这种调用方式是指在其声明函数中被调用即在其父函数中被调用。这种形式可以直接调用,如上例中plus函数直接在其父函数add中被调用。
2. 外部调用
函数内部声明的函数想要在外部调用可以通过作为函数的返回值赋值给外部变量来实现,请看下面的例子:
function add() {
var counter = 0;
function plus() {counter += 1; return counter;}
return plus;
}
var tempplus = add();
document.getElementById("demo").innerHTML = tempplus();
在本例中plus作为add函数的返回值赋值给变量tempplus ,通过tempplus 变量即可在函数外部访问内部函数plus
js函数闭包
函数闭包的概念:js解释器在遇到函数调用的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包,这些变量将不会被内存回收器所回收,只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包,而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收。
接下来我们用两个例子来说明一下:
1. 内部函数不被作为返回值,例如:
function animal() {
var high= 0;
function jump() {high+= 1;}
jump();
}
在animal被调用的时候,函数jump和变量high形成一个闭包。上例中jump没有作为返回值返回,也就是说函数jump不可能在外部被调用。也就是说在外部函数animal调用结束之后闭包中的jump就不可能再被调用了,那么这个闭包就会被销毁。
2. 内部函数被作为返回值,例如:
function animal() {
var high= 0;
function jump() {high+= 1; return high;}
return jump;
}
var dojump = animal() ;
同样的,在animal被调用的时候,函数jump和变量high形成一个闭包。不同的是函数jump被作为返回值赋值给了dojump ,也就是说在外部函数animal调用结束之后闭包中的jump还可能通过dojump 再被调用,这时闭包就会被保留,也就是每次调用dojump ,high变量都是在上一次调用的结果的基础上进行变更,也就是说:
var jump1= dojump () ; // jump1 = 1
var jump2= dojump () ; // jump2 = 2
var jump3= dojump () ; // jump3 = 3
直到dojump被赋值为其他的值,此闭包中的函数不可能被调用以后这个闭包才会被销毁。
补充说明
在上例中,animal每次被调用都会形成互不相干的一个闭包。例如:
function animal() {
var high= 0;
function jump() {high+= 1; return high;}
return jump;
}
var dojump = animal() ;
var rejump = animal() ;
var jump1= dojump () ; //jump1值为1
var jump2= dojump () ; //jump2值为2
var jump3= rejump () ; //jump3值为1
js特殊函数,箭头函数
箭头函数允许使用简短的语法来编写函数表达式。你可以不需要 function 关键字、return 关键字和花括号。注意只有在定义单语句函数时可以省略return 关键字和花括号,建议还是保留它们。IE11 或更早的版本不支持箭头函数。箭头函数举例:
//省略return 关键字和花括号
const x = (x, y) => x * y;
//不省略return 关键字和花括号
const x = (x, y) => { return x * y };
上例中x即为箭头函数,可以像这样调用它:
var result = x(5, 5);
箭头函数没有自己的 this。它们不适合定义对象方法。
箭头函数未被提升。它们必须在使用前进行定义。
使用 const 比使用 var 更安全,因为函数表达式始终是常量值。