JavaScript 是一門集成了函數編程和麪向對象編程的動態語言。它的對象是一個容器,封裝了屬性(property)和方法(method)。JavaScript的面向對象實現不是基於類,而是基於構造函數(constructor)和原型鏈(prototype)實現的。
一.概述
- 本文主要介紹了instanceof屬性,繼承和多重繼承。
instanceof
運算符介紹?instanceof
運算符返回一個布爾值,表示對象是否爲某個構造函數的實例。關鍵字左邊是實例,右邊是構造函數。檢測原理是:檢查右邊構造函數的prototype屬性,是否在左邊對象的原型鏈上。具體見: instanceof 運算符- 繼承和多重繼承介紹? 繼承有2種寫法,第一種寫法是在子類構造函數中,調用父類的構造函數。並且將子類的原型對象修改爲父類的原型。第二種寫法,子類的原型直接指向父類的一個匿名實例。具體見: 構造函數的繼承
二.instanceof 運算符
1.概念
-
概念:
instanceof
運算符返回一個布爾值,表示對象是否爲某個構造函數的實例。 -
概念:
instanceof
運算符的左邊是實例對象,右邊是構造函數。instanceof
的原理是檢查右邊構造函數的prototype屬性,是否在左邊對象的原型鏈上。//一. 左邊實例右邊構造函數 var v = new Vehicle(); v instanceof Vehicle // true //二. 檢查Vehicle的prototype是否在v實例的原型對象的原型鏈上 v instanceof Vehicle // 等同於 Vehicle.prototype.isPrototypeOf(v) //三. instanceof 檢查的是原型鏈,同一個實例對象,多個構造函數都返回true var d = new Date(); d instanceof Date // true d instanceof Object // true
2.使用
-
使用:判斷一個值是否爲
null
對象。由於任意對象(除了null)都是Object的實例。var obj = { foo: 123 }; obj instanceof Object // true null instanceof Object // false
-
使用:判斷值的類型
var x = [1, 2, 3]; var y = {}; x instanceof Array // true y instanceof Object // true
-
使用:利用instanceof運算符,還可以巧妙地解決,調用構造函數時,忘了加new命令的問題。
function Fubar (foo, bar) { if (this instanceof Fubar) { this._foo = foo; this._bar = bar; } else { return new Fubar(foo, bar); } }
3.注意
-
注意:instanceof判斷會失真,在左邊對象的原型鏈上,只有null對象。這時就會出現失真。
//Object.create(null)返回一個新對象obj,它的原型是null var obj = Object.create(null); typeof obj // "object" Object.create(null) instanceof Object // false
-
注意:
instanceof
運算符只能用於對象,不適用原始類型的值。總返回false。對於undefined
和null
,instanceof
運算符總是返回false。
三.構造函數的繼承
1.構造函數的單繼承
-
寫法:讓一個構造函數繼承另一個構造函數,第一種寫法是在子類構造函數中,調用父類的構造函數。並且將子類的原型對象修改爲父類的原型
//一. 第一步,子類的構造函數調用父類構造函數 function Sub(value) { Super.call(this); this.prop = value; } //二. 第二步,是讓子類的原型指向父類的原型 Sub.prototype = Object.create(Super.prototype); Sub.prototype.constructor = Sub; Sub.prototype.method = '...';
-
寫法:第二種寫法, 子類的原型直接指向父類的一個匿名實例
Sub.prototype = new Super();
-
範例一,構造函數整體繼承父類:
//一. 定義父類構造函數,並在原型對象上添加move方法 function Shape() { this.x = 0; this.y = 0; } Shape.prototype.move = function (x, y) { this.x += x; this.y += y; console.info('Shape moved.'); }; //二. 執行繼承 // 第1步,子類繼承父類的實例 function Rectangle() { Shape.call(this); // 調用父類構造函數 } // 第2步,子類繼承父類的原型 Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; //三. 驗證 var rect = new Rectangle(); rect instanceof Rectangle // true rect instanceof Shape // true
-
範例二,繼承父類的單個方法:
ClassB.prototype.print = function() { ClassA.prototype.print.call(this); // some code }
2.多重繼承
-
JavaScript 不提供多重繼承功能,即不允許一個對象同時繼承多個對象。但是,可以通過變通方法,實現這個功能。
function M1() { this.hello = 'hello'; } function M2() { this.world = 'world'; } function S() { M1.call(this); M2.call(this); } // 繼承 M1 S.prototype = Object.create(M1.prototype); // 繼承鏈上加入 M2 Object.assign(S.prototype, M2.prototype); // 指定構造函數 S.prototype.constructor = S; //子類S同時繼承了父類M1和M2。這種模式又稱爲 Mixin(混入) var s = new S(); s.hello // 'hello' s.world // 'world'