函数
在JS当中函数就是一个方法(一个功能体),基于函数一般都是为了实现某个功能
函数诞生的目的就是为了实现封装:把实现一个功能的代码封装到一个函数中,后期想要实现这个功能,只需要把函数执行即可,不需要再次编写重复的代码,起到了低耦合,高内聚的作用
作为值的函数
把函数结果作为参数
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);
arguments:函数内置的实参集合(不管你是否设置了形参,也不管你是否传递了实参)
是一个类数组对象,不能用数组中的方法,即使设置形参变量,形参该是什么值还是什么值,但是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;
}
arguments.callee
存储的是函数名
function sum(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
length
传入参数的个数
prototype
prototype是函数的一个属性,该属性的值是一个对象,被称为原型对象。当在原型对象中添加属性时,函数的实例对象也能访问。根据这个特性可以实现数据共享。
apply()
function sum(num1,num2){
return num1+num2;
}
function box(num1,num2){
return sum.apply(this,[10,10]);
}
call()
function sum(num1,num2){
return num1+num2;
}
function box(num1,num2){
return sum.call(this,10,10);
}
匿名函数与具名函数
具名函数
具名函数是在声明时指定了函数名称的函数
function fn(){
// do something
}
匿名函数
匿名函数是在声明时没有指定函数名称的函数
// 把匿名函数赋值给变量
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'
用对象冒充的方法改变 this 指向
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;
}();