如何产生闭包(条件)
- 函数嵌套
- 内部函数引用外部函数的局部变量
- 使用了外部函数(调用了外部函数)
闭包是什么
- 理解一: 闭包是嵌套的内部函数(绝大部分人)
- 理解二: 包含被引用变量(函数)的对象(极少数人)
- 理解三: 所谓的闭包是一个引用关系,该引用关系存在于内部函数中,引用的是外部函数的变量的对象(深入理解)
常见的闭包
- 将函数作为另一个函数的返回值
- 将函数作为实参传递给另一个函数调用
- 使用闭包实现私有方法操作独立的私有属性
闭包的作用
- 延长外部函数变量对象的声明周期
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
注意: 浏览器为了性能后期将外部函数中不被内部函数使用的变量清除了
闭包的声明周期
- 产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)
- 死亡: 在嵌套的内部函数成为垃圾对象时
面试题
//这不是闭包 ,内部函数没有引用外部的 变量
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () { // return 出来的这个函数就是单纯的函数,而不是方法;函数的this指向window,方法的this谁的方法this就指向谁
return this.name;
};
}
};
console.log(object.getNameFunc()());
运行结果 : “The Window”
var name2 = "The Window";
var object2 = {
name2: "My Object",
getNameFunc: function () {
var that = this;
return function () {
return that.name2;
};
}
};
console.log(object2.getNameFunc()());
运行结果 :“My Object”
function fun(n,o){
var n;
var o;
console.log(o);
return {
fun: function(m){
var m ;
return fun(m,n);
}
};
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
function Foo() {
getName = function () { alert (1); }; //没有var ,也是全局
return this; // window
}
Foo.getName = function () { alert (2);}; //构造函数的方法
Foo.prototype.getName = function () { alert (3);}; //实例化对象的方法
var getName = function () { alert (4);}; //全局
function getName() { alert (5);} //同名函数,被覆盖
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName(); //全局变成了1
getName();
new Foo.getName(); // new [ Foo.getName() ]
new Foo().getName(); // [ new Foo() ] .getName()
new new Foo().getName(); // 第一个new被忽略
var name = 'window'
var person1 = {
name: 'person1',
show1: function () {
console.log(this.name)
},
show2: () => console.log(this.name),
show3: function () {
return function () {
console.log(this.name)
}
},
show4: function () {
return () => console.log(this.name)
}
}
var person2 = { name: 'person2' }
person1.show1()
person1.show1.call(person2)
person1.show2()
person1.show2.call(person2)
person1.show3()()
person1.show3().call(person2)
person1.show3.call(person2)()
person1.show4()()
person1.show4().call(person2)
person1.show4.call(person2)()
person1.show1() ——// person1
person1.show1.call(person2) ——// person2person1.show2() ——// window
person1.show2.call(person2) ——// windowperson1.show3()() ——// window
person1.show3().call(person2) ——// person2
person1.show3.call(person2)()—— // windowperson1.show4()() ——// person1
person1.show4().call(person2) ——// person1
person1.show4.call(person2)() ——// person2
var name = 'window'
function Person (name) {
this.name = name;
this.show1 = function () {
console.log(this.name)
}
this.show2 = () => console.log(this.name)
this.show3 = function () {
return function () {
console.log(this.name)
}
}
this.show4 = function () {
return () => console.log(this.name)
}
}
var personA = new Person('personA')
var personB = new Person('personB')
personA.show1()
personA.show1.call(personB)
personA.show2()
personA.show2.call(personB)
personA.show3()()
personA.show3().call(personB)
personA.show3.call(personB)()
personA.show4()()
personA.show4().call(personB)
personA.show4.call(personB)()
personA.show1() ——// personA
personA.show1.call(personB) —— // personB
personA.show2() ——// personA
personA.show2.call(personB)—— // personA
personA.show3()() ——// window
personA.show3().call(personB) ——// personB
personA.show3.call(personB)()—— // window
personA.show4()() ——// personA
personA.show4().call(personB) ——// personA
personA.show4.call(personB)() ——// personB
参考链接:https://juejin.im/post/59aa71d56fb9a0248d24fae3