通过闭包实现类的静态变量:
var Book = (function (argument) {
// 静态私有变量
var bookNum = 0;
// 静态私有方法
function checkBook(name){}
// 创建类
function _book(newId, newName, newPrice){
// 私有变量
var name, price;
// 私有方法
function checkID(id){}
// 特权方法
this.getName = function(){};
this.getPrice = function(){};
this.setName = function(){};
this.setPRice = function(){};
// 共有属性
this.id = newId;
// 共有方法
this.copy = function(){};
bookNum++
if(bookNum > 100){
throw new Error('我们仅出版100本书.');
}
// 构造器
this.setName(name);
this.setPrice(price);
}
__book.prototype = {
// 静态共有属性
isJSBook: false,
// 静态公有方法
display: function(){}
}
// 返回类
return __book;
})()
创建对象的安全模式:
var Book = function(title, time, type){
// 判断执行过程中this是否是当前这个对象(如果是说明是用new创建的)
if(this instanceOf Book){
this.title = title;
this.time = time;
this.type = type;
// 否则重新创建这个对象
}else{
return new Book(title, time, type);
}
}
var book = new Book('javaScript','2014','js')
类主要由三部分组成:
- 第一部分是构造函数内的,这是供实例化对象复制用的;
- 第二部分是构造函数外的,直接通过点语法添加的,这是供类使用的,实例化对象访问不到;
- 第三部分是类的原型中的,实例化对象可以通过其原型链间接地访问到,也是为供所有实例化对象所共用的。
instanceof是判断前面的对象是否是后面类的实例;
创建的所有对象都是Object的实例。
实现继承:
-
类式继承:
新创建的对象不仅仅可以访问父类原型上的属性和方法,同样也可访问从父类构造函数中复制的属性和方法。你将这个对象赋值给子类的原型,那么这个子类的原型同样可以访问父类原型上的属性和方法以及父类构造函数中复制的属性和方法。这正是类式继承原理。
function SuperClass(){
this.superValue = true;
}
SuperClass.prototype.getSuperValue = function(){
return this.superValue;
}
function SubClass(){
this.subValue = false;
}
SubClass.prototype = new SubClass();
subValue.prototype.getSubValue = function(){
return this.subValue;
};
缺点:在创建父类的时候,无法向父类传递参数,因而在实例化父类的时候也无法对父类构造函数内的属性进行初始化;
-
构造函数继承:
对superClass调用这个方法就是将子类中的变量在父类中执行一遍,由于父类中是给this绑定属性的,因此子类自然继承了父类的共有属性。
function SuperClass(id) {
this.id = id
}
SuperClass.prototype.showBooks = funciton(){
console.log(this.id);
}
function SubClass(id){
SuperClass.call(this, id); // 构造函数继承精华
}
var instance1 = new SubClass(10) // =>10
instance1.showBooks() // TypeError
缺点:没有涉及原型prototype,父类的原型方法不被子类继承。因此instance1.showBooks()报错误TypeError
-
组合继承:
类式继承和构造函数继承的组合
function SuperClass(id){
this.books = ['html', 'css', 'javaScript'];
this.id = id;
}
SuperClass.prototype.showBooks = function(){
console.log(this.books)
}
function SubClass(id){
SuperClass.call(this, id) // 父类构造函数被调用第一次
}
SubClass.prototype = new SuperClass() // 父类构造函数被调用第二次
SubClass.prototype.showId = function () {
console.log(this.id)
}
var instance1 = new SubClass(10)
var instance2 = new SubClass(11)
instance1.books.push('设计模式')
instance1.showBooks() // ["html", "css", "javaScript", "设计模式"]
instance1.showId() // =>10
instance2.showBooks() // ["html", "css", "javaScript"]
instance2.showId() // =>11
缺点:父类构造函数被调用二次
-
原型式继承:
对类式继承的封装,过渡对象相当于类似继承的子类。
Object.create()方法
// 等于 Object.create()方法
function inheritObject (o) {
function f () {
}
f.prototype = o
return new f()
}
var book1 = {
name: 'js book',
alikeBook: ['css book', 'html book']
}
var book2 = inheritObject(book1)
// var book2 = Object.create(book1)
book2.name = 'flash book'
book2.alikeBook.push('as book')
var book3 = inheritObject(book1)
console.log(book1.name) // => js book
console.log(book1.alikeBook) // => ["css book", "html book", "as book"]
console.log(book2.name) // => flash book
console.log(book2.alikeBook) // => ["css book", "html book", "as book"]
console.log(book3.name) // => js book
console.log(book3.alikeBook) // => ["css book", "html book", "as book"]
缺点:跟类式继承一样,父类对象的book中的值类型的属性被复制,引用类型的属性被共用
-
寄生式继承:
对原型式继承的二次封装
function createBook (obj) {
var o = new inheritObject(obj);
// 拓展新对象
o.getName = function () {
console.log(this.name)
}
return o
}
var book4 = createBook(book1)
console.log(book4.name) // =>js book
console.log(book4.alikeBook) // =>["css book", "html book", "as book"]
book4.getName() // =>js book
-
寄生组合式继承:
综合上述的优点集合
// 寄生组合式继承
function inheritPrototype (subClass, superClass) {
var p = Object.create(superClass.prototype);
p.constructor = subClass;
subClass.prototype = p;
}
function SuperClass (name) {
this.name = name;
this.colors = ['red', 'yellow', 'blue'];
}
SuperClass.prototype.getName = function () {
console.log(this.name)
}
function SubClass (name, time) {
SuperClass.call(this, name);
this.time = time;
}
inheritPrototype( SubClass, SuperClass )
// SubClass.prototype = new SuperClass()
SubClass.prototype.getTime = function () {
console.log(this.time)
}
var instance1 = new SubClass('css book', 2014);
var instance2 = new SubClass('js book', 2019);
instance1.getTime()
instance1.getName()
instance2.getTime()
instance2.getName()
instance1.colors.push('black')
console.log(instance1.colors) // => ["red", "yellow", "blue", "black"]
console.log(instance2.colors) // => ["red", "yellow", "blue"]
网友评论