函数
函数arguments
function abc(a,b){
console.log(arguments[0])
}
abc(1,2)//打印1
为什么要用函数 高内聚 低耦合
return在函数中既是返回值也可以终止函数
预编译
1.imply global暗示全局变量:即任何变量,如果未经声明就赋值,此变量就位全局对象所有
eg: a = 123;
eg: var a = b =123;
如果在全局的情况下var a 则a属于全局变量window的属性
2.一切声明的全局变量,全是window的属性
eg:var a = 123; ==>windows.a = 123;
四部曲:
作用域
在每一个函数执行时生成一个执行上下文,在函数运行结束时销毁。
eg:
function a(){
function b(){
function c(){
}
c()
}
b()
}
a()// ==>调用前 [scope] 0:GO
//==>调用后 [scope] 0:GO
// 1:aAO
// b定义 [scope] 0:aAO
// 1:GO
// b执行 [scope] 0:bAO
// 1:aAO
// 2:GO
// c定义[scope] 0:bAO
// 1:aAO
// 2:GO
// c执行[scope] 0:cAO
// 1:bAO
// 2:aAO
// 3:GO
这里就解释了为什么外部不能调用函数内部的变量
闭包
当内部被保存到外部时,发生闭包。
闭包导致原有作用域链不释放,造成内存泄漏
优点:避免全局变量污染
缺点:会造成内存的滥用,
用处:实现公有变量
做缓存
实现封装,属性私有化
模块化开发,防止污染全局变量
立即执行函数
(function(){}())
只有表达式才能被执行符号执行
被执行符号执行的表达式,会忽略函数名
eg:闭包
function test(){
var arr = [];
for(var i = 0;i < 10;i++){
arr[i] = function (){
console.log(i)
}
}
return arr;
}
var myArr = test();
for(var j = 0;j < 10;j++){
myArr[j]();
}
//结果:10 10 10 10 10 10 10
解释:
因为在第一个for循环里面时只是循环生成函数并保存到数组中,并没有调用,所有console.log中的i还是i并没有赋值任何数,也没有进行打印。
在第二个for循环调用时,才生成函数作用域链,这时GO中的i是10,所以每次打印的都是10
想要解决闭包,使用立即执行函数
eg:
function test(){
var arr = [];
for(var i = 0;i < 10;i++){
(function (j){
arr[j] = function (){
console.log(j)
}
}(i))
}
return arr;
}