大廠面經-js基礎篇(必包/this)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章