在JS当中函数就是一个方法(一个功能体),基于函数一般都是为了实现某个功能
函数诞生的目的就是为了实现封装:把实现一个功能的代码封装到一个函数中,后期想要实现这个功能,只需要把函数执行即可,不需要再次编写重复的代码,起到了低耦合,高内聚的作用
ES3标准
function fn(){
//函数体:实现功能的代码
}
ES6标准
let 函数名(变量名)=([参数])=>{
函数体
}
// 赋值给变量
var box = function(num1,num2){
return num1+num2;
};
// 用构造函数
var fn = new Function('num1','num2','return num1+num2');
函数作为引用数据类型中的一种,它也是按照引用地址来操作的,接下来我们学习一下函数的运作机制
1.函数也是引用类型,首先会开辟一个新的堆内存,把函数体中的代码当做字符串存储到内存中(对象向内存中存储的是键值对)
2.把开辟的堆内存地址赋值给函数名
[函数执行]
目的:把之前存储到对内存中的代码字符串变为真正的JS代码自上而下执行,从而实现应用的功能
1. 函数执行,首先会形成一个私有的作用域(一个代码执行的环境,也是一个栈内存)
2. 把之前在堆内存中存储的字符串复制一份过来,变为真正的JS代码
参数是函数的入口:当我们在函数中封装一个功能 ,发现一些材料不确定,需要执行函数的时候用户传递进来才可以,此时我们就基于参数的机制,提供入口即可
//此处的参数为形参:入口,形参是变量
function sum(n,m){
var total = 0;
total = n + m;
console.log(total);
}
//此处函数执行传递的值是实参,实参是具体的数据值
sum(10)//n=10,m=undefined
sum();//n=undefined,m=undefined
sum(10,20,30)//n=10,m=20,30没有形参变量接收
函数可以通过 return 语句返回一个值,当函数遇到一个return就会停止运行并返回一个值
function box(){
return '返回一个值';
}
alert(box());
function pre(name,age){
return name+age;
}
alert(pre('ary',10));
var result=pre('ary',19);// 可以把函数返回的值赋给一个变量
alert(result);
把函数结果作为参数
function box(sum,num){
return sum+num;
}
function sum(num){
return num + 10;
}
var result = box(sum(10),10);// 输出30
把函数本身当做参数
function box(sum,num){
return sum(10)+num;
}
function sum(num){
return num+10;
}
var result = box(sum,10);
是一个类数组对象,不能用数组中的方法,即使设置形参变量,形参该是什么值还是什么值,但是ARG使用存储的是所欲传递进来的实参,所以它被称为实参集合。
arguments有一个length属性,可以用它获取实参的个数
function sum(){
var total=0;
for(var i=0;i<arguments.length;i++){
var item=arguments[i];
item=Number(item);
isNaN(item)?null:total+=item;
}
return total;
}
存储的是函数名
function sum(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
传入参数的个数
function sum(num1,num2){
return num1+num2;
}
function box(num1,num2){
return sum.apply(this,[10,10]);
}
function sum(num1,num2){
return num1+num2;
}
function box(num1,num2){
return sum.call(this,10,10);
}
// 把匿名函数赋值给变量
var fn=function (){
};
oBox.onclick=function (){
};
// 通过自我执行来调用匿名函数
(function (){
return 'Lee';
})();
// 把函数返回值赋值给变量
var fn = (function (){
return 'Lee';
})();
自我执行匿名函数的传参
var fn = (function (age){
return age;
})(100);
函数里放一个匿名函数
闭包是指有权访问另一个函数作用域里的变量的函数
闭包可以把局部变量驻留在内存中,避免使用全局变量
function box(){
return function (){
return 'Lee';
}
}
alert(box()());
闭包返回局部变量
function box(){
var age = 100;
return function (){
return age;
};
}
使用全局变量进行累加
var age = 100;
function sum(){
age++;
}
sum();
alert(age);
使用局部变量进行累加
function box(){
var age = 100;
age++; //每次执行时都会初始化
}
box();
alert(age);
使用闭包实现局部变量进行累加
function box(){
var age = 100;
return function (){
age++;
return age;
};
}
闭包在数组中的应用
function box(){
var arr = [];
for(var i=0;i<5;i++){
arr[i] = (function (num){
return function (){
return num
}
})(i);
}
return arr;
}
var b = box();
alert(b[i]());
闭包在运行时指向全局
var user = 'the window';
var box={
user : ' the box',
getUser : function (){
return function (){
return this.user;
}
}
};
alert(box.getUser()());// 输出'the window'
var user = 'the window';
var box={
user : ' the box',
getUser : function (){
return function (){
return this.user;
}
}
};
alert(box.getUser().call(box));
var user = 'the window';
var box={
user : ' the box',
getUser : function (){
// this 指向 box
var that = this;
return function (){
// this 指向 全局
return that.user;
}
}
};
alert(box.getUser()());
Javascript 不会提醒你是否多次声明同一变量,如果再次声明同一变量它会视而不见。
包含自我执行的匿名函数,可以实现私有作用域
function box(){
(function (){
for(var i=0;i<5;i++){
alert(i);
}
})();
// 这里可以继续使用 i 变量和上面的 i 变量没有关系
}
私有变量
function Box(value){
var user = value;
function run(){
return '运行中';
}
this.publicGo = function (){
return user+run();
}
this.getUser = function (){
return user;
}
}
实现接口方法共享
(function (){
var user = '';
Box.prototype.getUser = function (){
return user;
};
Box.prototype.setUser = function (value){
user = value;
};
})();
单例对象是永远只实例化一次
var box = function (){
var user = 'Lee';
function run(){
return '运行中';
}
var obj = {
publicGo : function (){
return user + run();
}
};
return obj;
}();
增强型
function Desk(){}
var box = function (){
var user = 'Lee'; // 私有变量
function run(){
return '运行中'; // 私有函数
}
var desk = new Desk();
desk.publicGo = function (){
return user + run();
};
return desk;
}();