闭包
指有权访问另一个函数作用域中的变量的函数
当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域,但闭包有所不同,在另一个函数内部定义的函数会被包含函数的活动对象添加到它的作用域链中,直到匿名函数被销毁后,才会被销毁
function createFunctions(){
var result=new Array()
for(var i=0;i<10;i++){
result[i]=function(){
return i
}
}
return result
}
//因为每个函数的作用域链中都保存着createFunctions()的活动对象,所以他们引用的都是同一个变量i
//解决方法:
1.
function createFunctions(){
var result=new Array()
for(var i=0;i<10;i++){
(function a(i){
result[i]=function(){
return i
}
})(i)
}
console.log(result[2]())
}
createFuncions()
2.
function createFuncions(){
var result=new Array()
for(var i=0;i<10;i++){
result[i]=function(i){
return function(){
return i
}
}(i)
}
console.log(result[2]())
}
关于this对象
匿名函数的执行环境具有全局性,因此其this对象通常指向window模仿块级作用域
for(var i=0;i<5;i++){
console.log(i)
}
var i//不会出错,JavaScript从来不会告诉你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见。不过,它会执行后续声明中的变量初始化
console.log(i)
(function(){
for(var i=0;i<5;i++){
console.log(i)
}
})()
console.log(i)//出错
- 私有变量
function MyObject(){
var privateVariable=10
function privateFunction(){
return false
}
this.publicMethod=function(){
privateVariable++
return privateFunction()
}
}
//在创建MyObject的实例后,除了使用publicMethod()这个途径,没有任何办法直接访问privateVarible和privateFunction()
- 静态私有变量
(function (){
var privateVarible=10
function privateFunction(){
return false
}
MyObject=function(){
}
MyObject.prototype.publicMethod=function(){
privateVarible++
return privateFunction()
}
})()
var o=new MyObject
console.log(o.publicMethod())
- 模块模式
var application=function(){
var components=new Array()
components.push(new BaseComponent())
return {
getComponentCount:function(){
return components.length
},
registerComponent:function(component){
if(typeof component=="object"){
components.push(component)
}
}
}
}
- 增强的模块模式
var application=function(){
var components=new Array()
components.push(new BaseComponent())
var app=new BaseComponent()
app.getComponentCount:function(){
return components.length
},
app.registerComponent:function(component){
if(typeof component=="object"){
components.push(component)
}
}
return app
}
- 递归
//1.
//严格模式下抛出错误
function factorial(num){
if(num<=1){
return 1
}else{
return num*arguments.callee(num-1)
}
}
//2.
var factorial=(function f(num){
if(num<=1){
return 1
}else{
return num*f(num-1)
}
})