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'