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