本文摘自 《JavaScript 设计模式》张容铭 著 版权归原作者所有
第2章 写的都是看到的---面向对象编程
2.2 封装
2.2.1 创建一个类
var book = function(id,bookname,price){
this.id = id;
this.bookname = name;
this.price = price;
}
book.prototype.display = function(){
//展示这本书
}
或者
book.prototype = {
display : function(){}
}
var book = new book(10,'一本书',50);
console.log(book.name); // 一本书
2.2.2 属性与方法封装
//私有属性与私有方法,特权方法,对象公有属性和对象共有方法,构造器
var Book = function(id,name,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(){
console.log('new Time')
}
Book.prototype = {
// 公有属性
isJSBook : false,
// 公有方法
disPlay : function(){}
}
2.2.3 闭包实现
有时我们经常将类的静态变量通过闭包来实现
// 利用闭包实现
var book = (function(){
// 静态私有变量
var bookNum = 0;
// 静态私有方法
function checkBook(name){
}
// 返回构造函数
return function(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('超额出售了');
// 构造器
this.setName(name);
this.setPrice(price);
}
_book.prototype = {
isJSBook : false,
display : function(){}
}
return _book;
})();
闭包是有权访问另外一个函数作用域中变量的函数,即在一个函数内部创建另外一个函数。
2.2.4 创建对象的安全模式
var book = function(title,name,type){
// 判断执行过程中this是否是当前这个对象(如果是说明是new创建的)
if(this instanceof Book){
this.title = title;
this.name = name;
this.type = type;
}else{
return new Book(title,name,type);
}
}
var book = Book('JS36个设计模式','2014','js');
console.log(book); // Book
console.log(book.title); // JS36个设计模式
console.log(book.name); // 2014
console.log(book.type); // js
console.log(window.title); // undefined
console.log(window.name); // undefined
console.log(window.type); // undefined
2.3 继承
2.3.1子类的原型对象——类式继承
// 类式继承
// 声明父类
function SuperClass(){
this.superValue = true;
}
// 为父类添加共有方法
SuperClass.prototype.getSuperValue = function(){
return this.superValue;
}
// 声明子类
function SubClass(){
this.SubValue = false;
}
// 继承父类
SubClass.prototype = new SuperClass();
SubClass.prototype .getSubValue = function(){
return this.SubValue;
}
var instance = new SubClass();
console.log(instance.superValue); // true
console.log(instance.SubValue ); // false
通过instanceof
来检测某个对象是否是某个类的实例。
console.log(instance instanceof SuperClass); // true
console.log(instance instanceof SubClass); // true
console.log(SubClass instanceof SuperClass); // false
// instanceof 是判断前面的对象实收是后面类的实例,它并不表示两者的继承。
继承父类时是将SuperClass 的实例赋值给SubClass的原型prototype,SubClass.prototype继承了SuperClass
console.log(SubClass.prototype instanceof SuperClass); // true
2.3.2 构造函数继承
// 构造函数式继承
// 声明父类
function SuperClass(){
// 引用类型共有属性
this.books = ['Javascript','html','css'];
// 值类型共有属性
this.id = id;
}
// 父类声明原型方法
SuperClass.prototype.showBook = function(){
console.log(this.book);
}
// 声明子类
function SubClass(id){
// 继承父类
// 由于call这个方法可以更改函数的作用环境,因此在子类中,对SuperClass调用这个方法就是将子类中的变量在父类中执行一遍,
// 由于父类中是给this绑定属性的,因此子类自然也就继承了父类的共有属性。
SuperClass.call(this,id);
}
// 创建第一个子类的实例
var instance1 = new SubClass(10);
// 创建第二个子类的实例
var instance2 = new SubClass(11);
instance1.books.push('设计模型');
console.log(instance1.books); // ['Javascript','html','css',‘设计模型’]
console.log(instance1.id); // 10;
console.log(insrance2.books); // ['Javascript','html','css']
console.log(instance2.id); //11
2.3.3 组合继承
// 组合式继承
// 声明父类
function SuperClass(name){
// 值类型共有属性
this.name = name;
// 引用类型共有属性
this.books = ['html','css','js'];
}
// 父类原型共有方法
SuperClass.prototype.getName = function(){
console.log(this.name);
}
// 声明子类
function SubClass(name,time){
// 构造函数式继承父类name属性;
SuperClass.call(this,name);
this.time = time
};
// 类式继承 子类原型继承父类
SubClass.prototype = new SuperClass();
// 子类原型方法
SubClass.prototype.getTime = function(){
consoel.log(this.time);
}
var instance1 = new SubClass('js book','2014');
instance1.books.push('设计模型');
console.log(instance1.books);// ['html','css','js','设计模型'];
instance1.getName();// js book
instance1.getTime(); // 2014
var instance2 = new SubClass('css book','2015');
console.log(instance2.books); // ['html','css','js'];
instance2.getName(); // css book
instance3.getTime(); // 2015
2.3.4 原型式继承
// 原型式继承
function inheritObject(o){
// 声明一个过渡函数对象
function F(){};
// 过渡对象的原型继承父对象
F.prototype = o;
// 返回过渡对象的一个实例,该实例的原型继承了父对象
return new F();
}
var book = {
name:'js book';
alikeBook:['css book','html book'];
}
var newBook = inheritObject(book);
newBook.name = 'ajax book';
newBook.alikeBook.push('xml book');
var otherBook = inheritObject(book);
otherBook.name = 'flash book';
otherBook.alikeBook.push('as book');
console.log(newBook.name); // ajax book
console.log(newBook.alikeBook); // ['css book','html book','ajax book']
console.log(otherBook.name); // flash book
console.log(otherBook.alikeBook); // ['css book','html book','as book']
console.log(book.name); // js book
console.log(book.alikeBook);// ['css book','html book']
2.3.5 寄生式继承
// 寄生式继承
// 声明基对象
var book = {
name:'js book',
alikeBook:['css book','html book']
};
function createBook(obj){
// 通过原型继承方式创建新对象
var o = new inheritObjet(obj);
// o.getName = function(){
console.log(name);
};
// 返回拓展后的新对象
return o;
}
2.3.6 寄生组合式继承
/**
* 寄生式继承 继承原型
* 传递参数 subClass 子类
* 传递参数 superClass 父类
**/
function inheritPrototype(subClass,superClass){
// 复制一份父类的原型副本保存在变量中
var p = inheritObject(superClass.prototype);
// 修正因为重写子类原型导致子类的constructor属性被修改
p.constructor = subClass;
// 设置子类的原型
subClass.prototype = p;
}
// 定义父类
function SuperClass(name){
this.name = name;
this.colors = ['red','blue','green'];
}
// 定义父类原型方法
SuperClass.prototype.getName = function(){
console.log(this.name);
}
// 定义子类
function SubClass(name,time){
// 构造函数式继承
SuperClass.call(this,name);
// 子类新增属性
this.time = time;
}
// 寄生式继承父类原型
inheritPrototype(SubClass,SuperClass);
// 子类新增原型方法
SubClass.prototype.getTime = function(){
console.log(this.time)
}
// 创建两个测试方法
var instance1 = new SubClass('js book',2014);
var instance2 = new SubClass('css book',2013);
instance1.colors.push('black');
console.log(instance1.colors);// ['red','blue','green','black']
console.log(instance2.colors);// ['red','blue','green']
instance2.getName();// css book;
instance2.getTime();// 2013
2.4 多继承
- 单继承实例
// 单继承 属性复制
var extend = function(target,source){
// 遍历源对象中的属性
for(var prototype in source){
// 将源对象中的属性复制到目标对象中
target[prototype] = source[prototype]
}
// 返回目标对象
return target;
}
var book = {
name:'JS设计模型',
alike:['css','html','JS']
}
var anotherBook = {
color:'blue'
}
extend(anotherBook.book);
console.log(anotherBook.name); // JS设计模型
console.log(anotherBook.alike);// ['css','html','JS']
anotherBook.alike.push('ajax');
another.name = '设计模式';
console.log(another.name); // 设计模式
console.log(another.alike); // ['css','html','JS','ajax']
console.log(book.name); // JS设计模型
console.log(book.alike); // ['css','html','JS','ajax']
- 多继承实例
// 多继承 属性复制
var mix = function(){
var i = 1, // 从第二个参数起为呗继承的对象
len = arguments.length, // 获取参数长度
target = arguments[0], // 第一个对象为目标对象
arg; // 缓存参数对象
// 遍历被继承的对象
for(; i < len; i++){
// 缓存当前对象
arg = arguments[i];
// 遍历被继承对象中的属性
for(var prototype in arg){
// 将被继承对象中的属性复制到目标对象中
target[prototype] = arg[prototype];
}
}
// 返回目标对象
return target;
}
或者
Object.prototype.mix = function(){
var i = 0, // 从第一个参数起为被继承的对象
len = arguments.length, //获取参数长度
arg; // 缓存参数对象
// 遍历被继承的对象
for(; i < len; i++){
// 缓存当前对象
arg = arguments[i];
// 遍历被继承对象中的属性
for(var prototype in arg){
// 将被继承对象中的属性复制到目标对象中
target[prototype] = arg[prototype];
}
}
}
otherBook.mix(book1,book2);
console.log(otherBook)
2.5 多态
//多态
function Add(){
// 无参数算法
function zero(){
return 10;
}
// 第一个参数算法
function one(num){
return 10+num;
}
// 两个参数算法
function two(num1,num2){
return num1+num2;
}
// 相加共有方法
this.add = function(){
var arg = arguments,
// 获取参数长度
len = arg.length;
switch(len){
// 如果没有参数长度
case 0:
return zero();
case 1:
return one(arg[0]);
case 2:
return two(arg[0],arg[1])
}
}
}
// 实例化类
var A = new Add();
console.log(A.Add()); // 10;
console.log(A.add(5)); // 15
console.log(A.add(6,6)); // 12
网友评论