1. 程式人生 > 其它 >3、JS的原型、原型鏈、執行上下文、作用域、作用域鏈+閉包(見1)

3、JS的原型、原型鏈、執行上下文、作用域、作用域鏈+閉包(見1)

1、原型

1.1、函式的prototype屬性

每個函式都有一個prototype屬性,預設指向一個object空物件(即原型物件)

原型物件中有一個屬性constructor,指向函式物件

1.2、給原型物件新增屬性(一般新增方法)

  函式的所有例項物件自動用於原型中的屬性(方法)

// 原型物件中有一個屬性constructor, 它指向函式物件
  console.log(Date.prototype.constructor===Date)//true
  console.log(fn.prototype.constructor===fn)//true

1.3 顯示原型和隱式原型

每個函式function都有一個prototype

,即顯示原型(屬性),定義函式時自動新增

每個例項物件都有一個__proto__,稱為隱式原型,建立物件例項時自動新增

物件的隱式原型的值對應其建構函式的顯示原型的值(儲存的是同一個地址

2、原型鏈+instanceof

2.1 訪問一個物件的屬性時,先在自身屬性中查詢,

如果沒有,再沿著__proto__這條鏈向上查詢,找到返回,沒找到返回undefined

//所有的函式都是Function的例項(包含Function,是它自身的例項)
  console.log(Function.__proto__===Function.prototype)
  //Object的原型物件(Object.prototype)是原型鏈的盡頭
console.log(Object.prototype.__proto__)

2.2設定原型屬性值時,不會查詢原型鏈,如果當前物件中沒有此屬性,就直接新增

2.3instanceof是按照原型鏈來判斷的,  typeof是返回資料型別的字串表示式

3、執行上下文

3.1程式碼分類

  全域性程式碼

  區域性(函式)程式碼

3.2全域性執行上下文

  在執行全域性程式碼之前,將window確定為全域性執行上下文

  對全域性資料進行預處理(var宣告的全域性變數,function宣告的全域性函式,this賦值window)

  開始執行全域性程式碼

3.3 函式執行上下文(只有在呼叫的時候才會產生)

  呼叫函式之前,建立相應的函式執行上下文

  對區域性資料進行預處理(形參賦值實參; 實參列表arguments; function宣告的函式; this賦值)

  開始執行區域性程式碼

3.4 函式執行上下文棧

  後來的先執行

3.5 測試

/*
  測試題1: 先預處理變數, 後預處理函式
          先執行變數提升,在執行函式提升
  */
  function a() {}
  var a;
  console.log(typeof a)//function

/* 測試題2: 變數預處理, in操作符 */ if (!(b in window)) { var b = 1; } console.log(b)//undefined /* 測試題3: 預處理, 順序執行 */ var c = 1 function c(c) { console.log(c) var c = 3 } c(2)//報錯,而且函式c沒有機會執行 //執行順序相當為 // var c // function c(c) { // console.log(c) // var c = 3 // } //c = 1 // c(2)

4、作用域和作用域鏈

全域性作用域、函式作用域,

在定義時就已經確定了,注意和上下文環境的區別,並且上下文環境是從屬於所在的作用域的

作用域鏈:巢狀的作用域,多個上下級關係的作用域形成的鏈