JavaScript对象的创建模式与继承模式示例讲解
作者:花铛
对象的创建模式
Object 构造函数模式:先创建空对象,再动态添加属性和方法。
适用场景:初始时对象内部数据不确定。
存在问题:语句太多(这个问题可以通过使用对象字面量模式来解决)。
var person = new Object() person.name = 'Tom' person.setName = function(name){ this.name = name }
使用对象字面量模式:使用 {}
创建对象,同时指定属性和方法。
适用场景:初始时对象内部数据是确定的。
存在问题:如果创建多个对象,有很多重复代码(这个问题可以通过使用工厂模式来解决)。
var person={ name:'Tom', setName: function (name){ this.name = name } }
工厂模式:通过工厂函数动态创建对象并返回。
适用场景:需要创建多个对象。
存在问题:对象没有具体的类型(这个问题可以通过使用自定义构造函数模式来解决)。
function createPerson(name) { var obj = { name: name, setName: function (name) { this.name = name } } return obj } var p1 = createPerson('Tom') var p2 = createPerson('Mary')
自定义构造函数模式:自定义构造函数,通过 new 创建对象。
适用场景:需要创建多个类型确定的对象。
存在问题:每个对象都有相同的数据(方法),浪费内存(这个问题可以通过使用构造函数 + 原型的组合模式来解决)。
function Person(name) { this.name = name this.setName = function(name) { this.name = name } } var p1 = new Person('Tom') var p2 = new Person('Mary')
构造函数 + 原型的组合模式:自定义构造函数,属性在函数中初始化,方法添加到原型上。
适用场景:需要创建多个类型确定的对象。
function Person(name) { this.name = name } Person.prototype.setName = function(name) { this.name = name } var p1 = new Person('Tom') var p2 = new Person('Mary')
对象的继承模式
原型链继承:
变量查找作用域链;对象的属性和方法查找原型链。
child.toString()
child.__proto__
= Child.prototype
----> Child.prototype
= new Object()
----> {}.__proto__
= Object.prptotype
child 能够访问到 toString 方法:是因为 child 实例能够访问到其原型对象上的方法;Child 构造函数的原型对象又指向 Object 构造函数的实例;{} 实例能够访问到其原型对象上的方法,因此顺着原型链 child 能够访问到 Object 构造函数原型对象上的方法。
// 父类型 function Parent() { this.parentProp = 'parent prop' } Parent.prototype.showParent = function() { console.log(this.parentProp) } // 子类型 function Child() { this.childProp = 'child prop' } // 让子类构造函数的 prototype 指向父类的实例对象,就可以形成子类 --- 父类的一条原型链,子类就可以访问到父类原型上的属性和方法。 Child.prototype = new Parent() // 如果此时 console.log(child.constructor) 会打印输出 Parent。 // 默认情况下,所有的原型对象都会自动获得一个 constructor 属性,指向原型对象所在的函数。因此 child 本身是没有 constructor 属性的,而是在它的原型对象身上;又因为它的原型对象指向了 Parent 的实例对象;Parent 实例对象的原型对象的 constructor 是 Parent,因此 child.constructor = Parent。这样是错误的。 Child.prototype.constructor = Child Child.prototype.showChild = function() { console.log(this.childProp) } var child = new Child() child.showParent()
借用构造函数继承:其实并没有真的实现继承,而是在子类构造函数中通过 call() 调用了父类的构造函数。
function Parent(name, age) { this.name = name this.age = age } function Child(name, age, price) { Parent.call(this, name, age) // 相当于执行 this.Person(name, age),也就是相当于 this.name = name; this.age = age this.price = price } const child = new Child('Tom', 20, 500) console.log(child.name, child.age, child.price)
组合继承:利用原型链继承实现对父类型的方法的继承;借用构造函数继承初始化相同的属性(真正在用的是这种方法)。
call() 是继承属性,重写原型是继承方法。
function Parent(name, age) { this.name = name this.age = age } Parent.prototype.setName = function(name) { this.name = name } function Child(name, age, price) { // 初始化相同的属性 Parent.call(this, name, age) this.price = price } // 继承父类的原型对象上的方法 Child.prototype = new Parent() // 修正 constructor 属性 Child.prototype.constructor = Child Parent.prototype.setPrice = function(price) { this.price = price } const child = new Child('Tom', 20, 500) console.log(child.name, child.age, child.price)
到此这篇关于JavaScript对象的创建模式与继承模式示例讲解的文章就介绍到这了,更多相关JS对象创建模式与继承模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!