函数
1.作用
(1) 功能的封装【方法】
将特定功能的代码封装起来,当需要的时候调用它才会执行。
(2)构建对象的模板【构造函数】
2.定义
(1)函数声明
function 函数名(形式参数){
函数体;
返回值;
}
例如:
function add(a,b){
var result = a + b;
return result;
}
var total = add(1,2);
函数声明会提升,也就是在执行所有代码之前,函数声明会先执行;
(2)函数表达式
var 函数名 = function(形式参数){};
例如:
var a = 3;
var obj = {};
var add = function(a,b){return a+b;};
var foo = add;
var bar = add;
3.函数调用
(1)函数名(实参);
(2)函数名.call(obj,实参列表);
调用指定函数名的函数,并且将obj赋值给该函数中的this
(3)函数名.apply(obj,实参数组);
调用指定函数名的函数,并且将obj赋值给该函数中的this
(4)函数名.callee;
4.函数在内存中的表现形式

一个函数可以有多个指针指向它
5. 函数的作用域
(1)函数内部声明的变量,在函数外部不能访问
(2)函数外部声明的变量,在函数内部可以访问,那这个时候,函数与外部的这个变量就组成了闭包。
(3)在js中函数内部不存在局部作用域
function foo(){
if(true){
var a = 3;
}
console.log(a); //打印结果为3
}
(4)如果想在函数中创建一个具有局部作用域的变量,如何实现?
- 使用let声明变量
function foo(){
let b = 4;
if(true){
let a = 3;
}
console.log(a); //报错
}
注:a只可以在if代码块中使用,b可以在函数中使用
2. 使用匿名函数的执行来虚拟局部变量
(function(){
if(true){
var b = 1;
}
})();
注:这种函数也称为立即执行函数,即在函数定义完就直接执行。这种函数往往只会执行一次,该函数内的变量不会影响全局变量
6.函数的内部属性
只有在函数内部才能访问、只有函数在执行过程中才能确定的属性
内部属性:(1)参数;(2)arguments;(3)this;
例如:
function add(a,b){
var result = a + b;
return result;
}
add(22,42,12,44);
(1)参数
形式参数是方法接受实参的快捷方式,真正的实参保存在arguments
(2)arguments
类数组对象,用于保存用户传入的实参
(3) this:【当前的执行对象】
this的取值与函数的调用方式有关
如果使用()调用函数,观察()左边是否是函数名,如果是函数名,继续观察函数名左边是否存在对象,如果是,那么this指向这个对象;如果不是指向全局对象(global/window)
例题:
var sayName = function(){
console.log("hello i am "+this.name);
}
var p1 = {
name:"terry",
age:12,
sayName:sayName
}
var p2 = {
name:"larry",
age:12,
sayName:sayName
}
sayName()--------------------> hello i am undefined
p1.sayName();----------------> hello i am terry
p2.sayName();----------------> hello i am larry
7. 引用传递,值传递【赋值是赋栈区的值】
(1)值传递:传递的是实际参数的一个副本
(2)引用传递:传递的是实际参数的地址
- 基本数据类型: Number, String等都是按值传递。
var a = 10
function add(num){
num+=10
return num
}
add(a)
console.log(a)----------------------> 10
console.log(add(a))-----------------> 20
a与函数内部的num互不干扰,它是按值传递的,复制了内存中的一份值给num。所以内部对num的操作不影响全局变量a的值
- 对象类型
var obj = {
name:'tom',
age:12
}
test1 :
function test1(obj){
obj.age++
}
test1(obj)
console.log(obj)-------------------> Object{name:"tom",age:13}
引用传递将指向函数的引用地址传递,两者同时指向函数
test2:
function test2(obj){
obj = null
}
test2(obj)
console.log(obj)-------------------> Object{name:"tom",age:12}
test3:
function test3(obj){
obj = {
name:'tom',
age:12
}
obj.age++
}
test3(obj)
console.log(obj)-------------------> Object{name:"tom",age:12}
总结:
值传递:内存中的地址复制了一份,修改数据指的是修改复制出来的内存地址,对原先的值不会有影响
【两把不同的锁,两把钥匙,所以互不影响】
引用传递:将其指向同一个内存地址,修改数据会对原先的值有影响
【两把钥匙,一把锁,相互影响】
8.函数作为值,实参,返回值
var a = function(){} 【匿名函数】
(1)函数当做实参
即回调函数:函数当做参数来传递
A对象调用B对象的C方法,C方法在执行的过程中又返回来调用A对象的D方法
function forEach(obj,handler){
for(var key in obj){
var val = obj[key];
handler.call(this,key,val);
}
var obj = {name:"terry",age:12};
forEach(obj,function(key,val){
console.log(key+"=="+val);--------------> name==terry
age==12
});
(2) 函数当做返回值
例如:工厂函数,即返回值return后返回的是一个function函数
function factory(prop){
return function(a,b){
if(a[prop]>b[prop]){
return 1;
} else {
return -1;
}
}
}
factory("age");
9.闭包
当内部函数指向外部函数的变量,外部函数执行完毕后,内部函数还未执行,这时候外部函数的变量不会释放与内部函数组成了一个闭包。
function foo(){
var arr = [];
for(var i =1; i<=100;i++){
arr[i] = function(){
console.log(i);
}
}
return arr;
}
var result = foo();
result[59]();---------------> 101
本文详细解析JavaScript函数的定义、调用、内部属性、作用域、参数传递方式及函数的多种应用,包括闭包和引用传递的概念。

被折叠的 条评论
为什么被折叠?



