JavaScript那些事--✪--原型鏈類、new和instanceof原理

創建對象幾種方法

四種創建方法,爲面向對象打下基礎

原型鏈類(原型、構造函數、實例、原型鏈)

構造函數

  • 定義把函數放在new操作符後面的函數叫構造函數。

    任何函數,只要通過new操作符調用,就是構造函數,如果不是new調用的,則和普通函數不會有什麼兩樣。

  • 一般寫構造函數的名字時,首字母是大寫
  • 所有的引用類型都是有構造函數
var a = {} // 其實是var a =new Object()的語法糖
var a = [] // 其實是var a =new Array()的語法糖
function Foo(){...} // 其實是var Foo = new Function(){....}

原型、實例

首先看下面代碼:

  function Person(name) {
    this.name = name
  }
  var m = new Person('我愛羅')
  • new Person創建了一個實例m【就是一個具體化的產品】。
  • 聲明函數Person的時候,JS引擎會給函數自動增加一個屬性prototype初始化爲空對象,也就是原型對象即原型。
    在這裏插入圖片描述
    問:那我怎麼知道這個原型對象是被哪個構造函數引用?
    答:實際上原型對象上有個構造器(constructor),構造器會默認爲你聲明的函數。
    在這裏插入圖片描述

原型鏈

實例對象往上找構造這個實例的原型對象,然後再往上找原型對象之上的原型對象,以此類推一直找到Object.prototype(原型鏈頂端)

  Person.prototype.say = function () {
    console.log('hi')
  }
  var m1 = new Person('李洛克')

在這裏插入圖片描述
如果實例中沒有這個方法則會通過__proto__ 到原型對象上找,如果還是沒有再往上,以此類推。如果到Object.prototype還是沒有找到,則報錯沒定義這個方法。
在這裏插入圖片描述
這個裏面也可以看到構造函數中會增加了很多方法和屬性,當我們創建多個實例的時候,可以避免每個都copy一份,而是存在他們共同的地方-原型對象

溫馨提示: 創建對象使用Object.create方法爲什麼返回時空?
因爲Object.create是把參數作爲一個新對象的原型對象賦給實例,實例本身不具備屬性,只能通過原型鏈查找。

原型鏈類總結:

在這裏插入圖片描述
原型規則:

  1. 所有引用類型都具備對象特性,即可自由擴展屬性。
var obj = {};obj.a=100
var arr = []; arr.a =100
function fn() {} 
fn.a=100
  1. 所有引用類型都有一個__proto__(隱式類型)屬性,屬性是一個普通對象。
    在這裏插入圖片描述
  2. 所有函數都有一個prototype(顯式類型)屬性,屬性值是一個普通對象。
  3. 所有引用類型的__proto__屬性值指向(完全等於)它的構造函數prototype屬性值
    在這裏插入圖片描述
  4. 當試圖得到一個對象的屬性或方法時,如果本身沒有,則會從它的__proto__尋找,一直找到原型鏈頂點。

instanceof原理

在這裏插入圖片描述
繼續拿這個爲例子

  function Person(name) {
    this.name = name
  }
  var m = new Person('我愛羅')
  console.log(m instanceof Person) // true

m instanceof Person原理是,m的__proto__一層層往上,能否對應到Person.prototype,找到則返回true。
這種判斷也不時很嚴謹因爲,m instanceof Object也是true。最嚴謹的方法是用構造器(constructor)
在這裏插入圖片描述

new 運算符

  1. 一個新對象被創建,它繼承這個函數的原型對象(foo.prototype)。
  2. 構造函數foo被執行。執行的時候,相應的傳參會被傳入,同時上下文(this)會被指定爲這個新實例。new foo 等同與new foo(),只能用在不傳遞任何參數的情況。
  3. 如果構造函數返回了一個對象,那麼這個對象會取代整個new出來的結果。如果構造函數沒有返回對象,那麼new出來的結果爲步驟1創建的對象。
var new2 = function (func) {
    var o = Object.create(func.prototype)
    var k = func.call(o)
    if (typeof k === 'object') {
      return k
    } else {
      return o
    }
  }
 var m2 = new2(Person)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章