js前端面試題一句話說完經典問題

做用域

做用域是變量和函數生效的區域。分爲全局變量和局部變量。函數外面不能訪問函數裏面的,函數裏面的能夠訪問函數外面的。彼此獨立的區間不能互相訪問。 每一個js的函數都是一個對象,對象有些屬性咱們能夠訪問,有些只能供js引擎存取,咱們訪問不了。[[scope]]就是其中之一。scope就是咱們所說的做用域,其中存儲了執行期上下文的集合。這個集合成鏈式結構,咱們把這個連式結構稱做做用域鏈。 當函數執行的前一刻,會建立一個稱爲執行期上下文的內部對象。一個執行期上下文定義一個函數執行環境,函數每次執行對應的執行上下文都是獨一無二的。因此屢次調用一個函數會致使建立多個執行期上下文,當函數執行完畢時候,執行期上下文就會被銷燬。數組

js運行三部曲

  • 語法解析
  • 預編譯
  • 解析執行

預編譯

預編譯分爲函數預編譯和全局預編譯 預編譯總共有四個步驟,第一個先建立一個AO對象(activation object),也叫做執行期上下文。第二個找到形參和變量聲明,將變量和形參名做爲AO的屬性,值爲undefined。第三部是實參和形參相統一,把實參值傳到形參中。第四部將函數聲明提高,值賦給函數體。 全局預編譯是首先建立一個GO對象(blobal object),window就是GO。AO上面沒有就看GO.緩存

閉包

當內部函數被保存到外部時,將生成閉包,閉包會致使做用域鏈不釋放,形成內存泄漏。閉包

  • 實現公有變量(累加器)
  • 作緩存 (存儲結構)
  • 實現封裝,屬性私有化
  • 模塊開發防止污染全局變量

構造函數

構造函數必須用new 這個操做符,構造函數內部原理是使用new以後,裏面會有三步隱式轉換。app

  • 在函數體最前面隱式的加上 var this = {} 空對象
  • 執行 this.xxx = xxx
  • 隱式的返回 return this

原型

原型是function對象的的一個屬性,他定義了構造函數製造出來的對象的公有祖先。經過該構造函數產生的對象,能夠繼承原型的屬性和方法。原型也是對象。 使用原型能夠提取出來公有屬性。對象屬性的增刪和原型上屬性的增刪改查。對象經過__proto__ 查看原型。對象可經過constructor查看構造函數。函數

原型鏈

函數的原型是另外一個構造函數,另外一個構造函數有原型,就造成原型鏈。原型鏈上的增刪改查和原型基本一致,只有本人有的權限,資損失沒有的。 誰調用的方法內部this就指向誰。絕大多數的對象最終都會繼承自Object.prototype 除了 Object.create(null?原型)this

繼承

  • 原型鏈繼承
  • 借用構造函數繼承 call applay
  • 共享原型
  • 聖盃模式 另外加一箇中間構造函數存儲原型

this

  • 預編譯 this 指向 window
  • 全局做用域 this 指向 window
  • call/applay 可改變函數運行時候this的指向
  • obj.func() func() 裏的 this 指向obj 誰調用指向誰

深度克隆的步驟

  • 一、先把全部的值都遍歷一遍(看是引用值和原始值) 用 for ( var prop in obj ),對象和數組均可以使用
  • 二、判斷是原始值,仍是引用值?用 typeof 判斷是否是 object 1)若是是原始值就直接拷貝 2)若是是引用值,判斷是數組仍是對象
  • 三、判斷是數組仍是對象?(方法 instanceof【看 a 的原型鏈上有沒有 b 的原型】、 toString、constructor,建議用 toString,另外兩個有個小 bug——跨父子域不行) 1)若是是數組,就新建一個空數組; 2)若是是對象,就新建一個空對象。
  • 四、創建了數組之後,若是是挨個看原始對象裏面是什麼,都是原始值就能夠直接考 過來了;或者,創建了對象之後,挨個判斷對象裏面的每個值,看是原始值仍是 引用值
  • 五、遞歸
相關文章
相關標籤/搜索