var Book = function(id,bookname,price){
this.id = id
this.bookname = bookname
this.price = price
}
Book.prototype.display = function(){}
2)将对象赋值给类的原型对象
Book.prototype = {
display: function(){}
}
以上两者区别:
通过this添加属性、方法 | 通过prototype继承属性、方法 |
---|---|
该对象独有的属性和方法,再创建新对象时,需要重新创建属性和方法 | 创建新对象无需重复创建属性和方法 |
在当前对象上添加的 | 添加到prototype中 |
js实现方式:
// 私有属性和私有方法,特权方法,对象共有属性和对象共有方法,构造器
var Book = function(id, bookname, price){
var num = 1 // 私有属性
// 私有方法
function checkId(){
}
// 特权方法
this.getName = function(){}
this.getPrice = function(){}
this.setName = function(){}
this.setPrice = function(){}
// 对象共有属性
this.id = id
// 对象共有方法
this.copy = function(){}
// 构造器
this.setName(name)
this.setPrice(price)
}
// 类静态共有属性
Book.isChinese = true
// 类静态共有方法
Book.resetTime = function()[]
Book.prototype = {
// 共有属性
isJSBook: false,
// 共有方法
display: function(){}
}
var b = new Book(11,'lala',50)
console.log(b.num) // undefined
console.log(b.isJsBook) // false
console.log(b.id) // 11
console.log(b.isChinese) // undefined
有时将类的静态变量通过闭包来实现
var Book = (function(){
var num = 1 // 静态私有属性
// 静态私有方法
function checkId(){
}
return function(newId, newName, newPrice){
// 私有变量
var name,price
// 私有方法
function checkId(){}
// 特权方法
this.getName = function(){}
this.getPrice = function(){}
this.setName = function(){}
this.setPrice = function(){}
// 对象共有属性
this.id = id
// 对象共有方法
this.copy = function(){}
// 构造器
this.setName(name)
this.setPrice(price)
}
// 构造原型
_book.prototype = {
// 静态共有属性
isJsBook: false;
// 静态共有方法
display: function(){}
}
// 返回类
return _book
})();
// 声明父类
function Book () {
this.name = '计算机'
}
// 为父类添加方法
Book.prototype.getName = function () {
return this.name
}
// 声明子类
function pattern() {
this.patternCom = '设计模式'
}
// 继承父类
pattern.prototype = new Book()
//为子类添加方法
pattern.prototype.getPattern = function () {
return this.patternCom
}
类式继承缺点:
(1)因为子类是通过其prototype对父类进行实例化继承父类,若父类中的共有属性是引用类型的话,就会在子类中被所有实例共用。因此在子类实例中更改从父类继承过来的共有属性会影响到其他子类。
(2)无法向父类传递参数,因而也无法在实例化父类时对构造函数内属性进行初始化。
// 声明父类
function Book (id) {
this.name = '计算机'
this.id = id
}
// 为父类添加方法
Book.prototype.getName = function () {
return this.name
}
// 声明子类
function pattern(id) {
Book.call(this,id)
}
call()可以更改函数的作用环境,使子类变量在父类中执行一遍,可以继承父类的共有属性。
第一次:构造函数继承时执行了一遍父类构造函数
第二次:实现子类继承时,调用了父类构造函数
// 声明父类
function Book (id) {
// 声明一个过渡函数对象
function pattern() {}
// 过渡对象的原型继承父类对象
pattern.prototype = id
// 返回过渡对象的实例,该实例原型继承了父对象
return new pattern()
}
/ 声明父类
function Book (id) {
// 声明一个过渡函数对象
function pattern() {}
// 过渡对象的原型继承父类对象
pattern.prototype = id
// 返回过渡对象的实例,该实例原型继承了父对象
return new pattern()
}
var book = {
name: '123'
}
function createBook(obj) {
// 通过原型继承方式创建新对象
var o = new Book(obj)
// 拓展新对象
o.getName = function(){}
// 返回拓展后的新对象
return o
}
寄生式继承就是对原型继承的第二次封装,并在第二次封装是对继承的对象进行了拓展,这样新创建的对象中不仅有父类的属性和方法还有新创建的属性和方法。
// 声明父类
function inheritobject (id) {
// 声明一个过渡函数对象
function pattern() {}
// 过渡对象的原型继承父类对象
pattern.prototype = id
// 返回过渡对象的实例,该实例原型继承了父对象
return new pattern()
}
/*
* subclass: 子类 superclass: 父类
* */
function inheritprototype(subclass, superclass) {
// 缓存父类原型
var p = inheritobject(subclass.prototype)
// 修正子类的constructor
p.constructor = subclass
// 设置子类的原型
subclass.prototype = p
}