js基礎知識梳理

satomiyoyi07發表於2019-02-17

從問題入手

學習知識基礎是關鍵。在此記錄關鍵問題,不斷豐富。僅供自己學習。

問題

  • js記憶體分幾類?分別用來存放什麼?
  • 全域性作用域和私有作用域
  • 記憶體釋放
  • 什麼叫預解釋?
  • 全域性變數和私有變數
  • 函式執行基本順序
  • 程式碼執行變數獲取順序
  • 解釋閉包
  • this的指向
  • 前端常接觸的設計模式
  • var n1 = new Number和var n2 = 1有什麼不同?var a1 = new Array和var a2 = []有什麼不同?
  • 解釋一下js的原型鏈

  • js記憶體分幾類?分別用來存放什麼?

answer:js分為棧記憶體和堆記憶體

堆記憶體用來存放引用資料型別的具體內容,object型別儲存key value;function型別用來存放函式內容的字串

棧記憶體用來提供一個js程式碼執行的環境。全域性作用域和私有作用域都屬於棧記憶體。

  • 全域性作用域和私有作用域?

answer:

全域性作用域:瀏覽器一開啟就建立,瀏覽器關閉時才銷燬。 私有作用域:函式執行才產生私有作用域。

  • 記憶體釋放?

answer:

堆記憶體釋放:引用資料型別定義的時候開闢一個新的堆記憶體,該記憶體有個引用地址。如果存在變數引用該地址,則記憶體被佔用不可銷燬。若想釋放,則把他的記憶體指向null,當前堆記憶體沒有被佔用,則瀏覽器會在空閒時銷燬。

棧記憶體釋放:全域性作用域瀏覽器一開啟即建立,關閉才銷燬。私有作用域,函式執行時產生,私有作用域的程式碼執行完了,則當前作用域被銷燬。

但是,當前私有作用域的部分內容被當前作用域之外的內容佔用了,當前作用域不能銷燬

  1. 函式執行返回一個引用資料型別的值,並且在函式外被接收了。這種情況行程的私有作用域不會被銷燬,比如返回一個函式、物件、陣列、則該堆記憶體無法釋放,與此同時,執行該堆記憶體的執行棧記憶體也無法釋放。但是返回數字,字串,布林值,則直接返回值,函式執行產生的私有作用域執行一次銷燬一次。
  2. 私有作用域中進行dom事件繫結,因為dom事件繫結,則該私有作用域也不能釋放(dom繫結相當於返回一個函式,和情況1本質相同)。
  3. 函式執行返回的函式並沒有被其餘變數接收,但是會緊接著執行一次,則該記憶體不會立即銷燬,在執行完畢後再銷燬。
function fn(){
    var num = 100;
    return function(){
        
    }
}
fn()()
複製程式碼
  • 什麼叫預解釋?

answer:也叫變數提升。在當前作用域中,js程式碼執行之前,瀏覽器首先會把帶var 和 function 的進行提前宣告或定義。(var 宣告 function 宣告+定義)

預解釋只發生在當前作用域下,開始只對window下(全域性作用域)下預解釋,函式執行時對(私有作用域)下進行預解釋。全域性和私有作用域都存在預解釋。

  • 全域性變數和私有變數?

answer:

全域性變數:全域性作用域下定義的變數(全域性下預解釋)

私有變數:私有作用域中宣告的變數 和 函式的形參。

  • 函式執行基本順序?

answer:

  1. 生成一個新的私有作用域
  2. 如果有形參,先形參賦值
  3. 在私有作用域中進行預解釋
  4. 在私有作用域中從上到下執行程式碼
  • 函式執行變數獲取順序?

answer:

  1. 先確定私有變數中是否存在(形參+宣告的私有變數),如果有優先使用私有變數。
  2. 如果沒有則向上級作用域查詢,直到window為止。
  3. 上級作用域只和函式定義有關,和在哪執行無關。在哪個作用域下定義的,上級作用域就是誰。
  • 解釋閉包?

answer:閉包是一種機制,函式執行時產生的私有作用域內的變數保護起來,不受外界干擾。

  • this的指向?

answer:僅代表當前行為的執行主體

和的當前執行的環境(區域)上下文無關; 和函式在哪定義,在哪執行無關;

  1. 函式執行,函式名前面有.則.前面為this;沒有.window為this;
  2. 自執行函式中,this永遠指向window;
  3. 給dom元素繫結事件,當前事件觸發執行繫結方法,方法中的this執行當前dom元素。
  4. 建構函式模式中,函式體中(類中)的this中,指向當前類的一個例項。
  • 前端常接觸的設計模式 answer:
  1. 單例模式:分組編寫各自的功能模組。
  2. 工廠模式:相同功能程式碼,抽取到一個函式處理。
  3. 建構函式模式:建立類,並利用類的例項。
function Fn(){
    this.x = 100;
}
Fn.prototype.getX = function(){};
var f1 = new Fn
複製程式碼
建構函式模式注意點:
1. 不需要傳參時,()可以省略。
2. 建構函式中的this指向某個例項,但是屬性值內包含this,需要看.前面的內容。
複製程式碼
function Fn(){
    this.x = 100;
    this.getX = function(){
        console.log(this.x)
    }
}
var f1 = new Fn
複製程式碼
3. 建構函式裡的var只是私有變數而已,和類、例項無關。
4. 建構函式模式中,**瀏覽器預設把例項返回**,返回一個**物件資料型別**的值。如果自己在建構函式中寫return。return 基本資料型別的值,則當前例項不變。若return 引用資料型別,則當前例項為該引用資料型別。
複製程式碼
function Fn(){
    this.x = 100;
    return [1,2,3]
}
var f1 = new Fn;
console.log(f1); // [1, 2, 3]
複製程式碼
  1. 原型鏈模式:在建構函式基礎上,解決屬性共有問題。
  • var n1 = new Number和var n2 = 1有什麼不同?var a1 = new Array和var a2 = []有什麼不同?

answer:

new的形式是例項建立方式,n=1是物件字面量方式。前者是標準建立例項的方式。第二種是js弱型別語言獨有的建立例項的方式。

針對引用資料型別:物件字面量,和類例項方式建立沒有不同。 針對基本資料型別:兩者不同。

var n1 = new Number(1);
var n2 = 1;
typeof(n1) // object
typeof(n2) //number
n1 instanceOf Number //true
n2 instanceOf number // false
複製程式碼
  • 解釋一下js的原型鏈

答:

* 每個函式資料型別,都自帶一個prototype屬性,屬性值為物件資料型別
* prototype在瀏覽器環境下,擁有一個constructor屬性,值為當前函式本身
* 每個物件資料型別(普通物件,例項,prototype),也天生自帶一個屬性__proto__。指向`當前例項所屬類的原型(prototype)`
複製程式碼

相關文章