關於構造函數和原型
構造函數:相當於java中“類”的存在,如原生JS中的Array, Function, String, Date
等等,都是構造函數。例如new Date()
通過new操作符進行調用,用來創建一個Date對象的實例。
一個便於理解的栗子,描述js通過原型模式實現繼承的過程
function Animal (name) { // 構造函數 this.name = name } Animal.prototype.type = 'animal' // 原型上的屬性和方法可以被繼承 Animal.prototype.eat = function () { console.log('eat') } let dog = new Animal('忠犬八公') // 通過new 調用構造函數創建Animal的實例dog console.log(dog.name) // 輸出:忠犬八公 console.log(dog.type) // 輸出:animal dog.eat() // 輸出:eat console.log(dog.__proto__) // 輸出:{ type:'animal', eat: f, __proto__: ...} // dog.__proto__ 指向其構造函數Animal的prototype對象
一個關於原型的實用型例子
function Elem(id) { this.elem = document.getElementById(id) } Elem.prototype.html = function (val) { var elem = this.elem if (val) { elem.innerHTML = val return this // 鏈式編程 }else{ return elem.innerHTML } } Elem.prototype.on = function (type, fn) { var elem = this.elem elem.addEventListener(type, fn) } var div1 = new Elem('div1') div1.html('灶門碳治郎').on('click', (e) => { alert('灶門碳治郎') })
這個栗子,使用原型將對dom
節點的操作封裝起來,只要創建一個Elem實例就輕松插入dom
和添加事件監聽。
原型鏈
所有的引用類型會有一個__proto__
屬性指向其構造函數的prototype
,當訪問這個引用類型的變量和方法時,會通過__proto__
屬性一層層往上找。如[]
不止有構造函數Array
原型上的方法,還有可以通過原型鏈找到Object
原型上的方法。
關於instanceof 和 constructor
instanceof
:判斷操作符右邊的參數是否在左邊的原型鏈上。所以[] instanceof Object
也為true
let obj = {} let arr = [] console.log(typeof(obj)) // object console.log(typeof(arr)) // object console.log(obj instanceof Array) // false console.log(arr instanceof Array) // true console.log(obj.constructor === Array) // false console.log(arr.constructor === Array) // true
通過以上代碼可以學習通過instanceof
關鍵字和constructor
屬性進行數據類型判斷的使用方式。
知識延伸
先有雞還是先有蛋
JS究竟是先有Object還是先有Function呢?
console.log(Function instanceof Object) // 輸出:true console.log(Object instanceof Function) // 輸出:true
Object和Function究竟是什么關系,這個問題一度困擾着我,直到我看到了這張圖
簡單理解為:
Function
在Object
的原型鏈上,因為Object
是構造函數,他的__proto__
指向Function
的原型Object
在Function
的原型鏈上,因為Function
是構造函數,他的__proto__
指向的也是他自己的原型,然而Function.prototype
本質上是一個對象,所以Function.prototype.__proto__
指向Object.prototype
。
關於鏈式編程
上述“一個關於原型的實用例子”中,提到了鏈式編程,在此做簡單介紹
function Dog(){ this.run = function(){ alert('dog is run...') return this // 鏈式編程的關鍵 } this.eat = function(){ alert('dog is eat...') return this } this.sleep = function(){ alert('dog is sleep...') return this } } var d1 = new Dog() d1.run().eat().sleep()
通過以上代碼可以看出
- 鏈式編程的設計模式就是,調用的函數的時候,可以基於其返回值繼續調用其他方法。
- 關鍵在於方法執行結束后需要有一個供繼續調用的返回值,如
this
等。
引用https://www.cnblogs.com/rainykane/p/12047477.html