1. 必包
1.1 什么是必包
必包是js语言的一种特性,主要包含的要点是函数会形成单独的作用域,同作用域的对象可以互相访问,作用域呈层级包含状态,形成作用域链,子作用域的对象可以访问父作用域的对象,反之不能。
比如我们在a函数里面返回b函数,当 b 函数执行的时候,a函数上下文已经被销毁了啊,但是我们依然能读取到a作用域下的值?这是因为作用域链导致的,b函数引用了 a函数活动对象中的值的时候,即使 a的执行上下文被销毁了,但是 js依然会让 a函数活动对象活在内存中,b函数依然可以通过 b 函数的作用域链找到它,正是因为 js 做到了这一点,从而实现了闭包这个概念。
1.2 必包的应用场景以及副作用
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中
- 实现变量的私有化,可以将私有变量放在一个函数里,然后以闭包的形式,在该函数里创建特权函数来访问和操纵这些变量。
function MyObject(){
//私有变量
var privateVariable = 10;
//私有函数
function privateFunction(){
return false;
}
//特权方法
this.publicMethod = function(){
privateVariable++;
return privateFunction();
};
}
副作用:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,解决方法是,在退出函数之前,将不使用的局部变量全部删除。
1.3 关于必包的常出现的考题
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
};
}
// 参考https://www.cnblogs.com/xxcanghai/p/4991870.html 有点难
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()()); //The Window
2. this
1. 什么是this
- 全局执行上下文中(在任何函数体外部)this 都指代全局对象
- 在函数内部,this 的值取决于函数被调用的方式
- 使用call/apply/bind 改变this的绑定
- 当函数作为对象里的方法被调用时,它们的 this 是调用该函数的对象(对于在对象原型链上某处定义的方法,同样的概念也适用)
- 当一个函数用作构造函数时(适用 new 关键字),它的 this 被绑定到正在构造的新对象
- foo 的 this 被设置为他被创建时的上下文,这同样适用于在其他函数内创建的箭头函数:这些箭头函数的 this 被设置为封闭的词法上下文的。箭头函数没有自己的 执行上下文,this 和 arguments 都是从它们的父函数继承而来的
2. this面试题目
var object = {
foo: 'bar',
func:function(){
var self = this
console.log(this.foo)
console.log(self.foo)
(function(){
console.log(this.foo)
console.log(self.foo)
}())
}
}
object.func()
// bar
// bar
// undefined
// bar
var obj1 = {
name: 'obj1',
sayName:function sayName(){
console.log(this.name)
}
}
name = 'name'
var obj2 = {name:'obj2'}
var obj3 = {
name: 'obj3',
sayName:function(){
(function(){
console.log(this.name)
})()
}
}
var obj4 = {
name: 'obj4',
sayName:() => {
console.log(this.name)
}
}
obj1.sayName() //obj1
obj3.sayName() // name
obj4.sayName() // name
obj1.sayName.call(obj2) //obj2
obj3.sayName.call(obj2) // name
obj4.sayName.call(obj2) //name