javascript设计模式之面向对象编程

面向对象编程就是将你的需求抽象成一个对象,然后针对这个对象分析其特性(属性)与动作(方法)。

面向对象思想:对一些属性方法的隐藏与暴露,比如私有属性、私有方法、共有属性、共有方法

栗子:

//创建一个类

var People = function(){
}

People.prototype={
	Skill:function() {
		console.log('我拥有技能')

		return this;//返回原型对象
	},
	Sleep:function() {
          console.log('I can sleep')
          return this;
	},
	Eat:function() {
		console.log('I can eat')
		return this
	}
}

var people = new People()
people.Skill().Sleep().Eat()

面向对象编程特点之一就是封装,而闭包就是封装的很典型的方式

闭包,有权访问另外一个函数作用域中变量的函数,即在一个函数内部创建另外一个函数

栗子:

var Book = (function() {
	//静态私有变量
	var bookNum = 0;
    //静态私有方法
    function checkBox(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('错误啦');
    	//构造器
    	this.setName(name);
    	this.setPrice(price);
    }
    _book.prototype = {
    	isJSBook : false,
    	display:function(){}
    }
    return _book;//返回类
})();

//创建对象的安全模式
//为了避免在创建一个新对象时忘记new
var Book = function(title,time,type) {
	//判断执行过程中this是否是当前这个对象(如果是说明是用new创建的)
	if(this instanceif Book) {
		this.title = title;
		this.time = time;
        this.type = type;
	}else{
		//否则重新创建这个对象
		return new Book(title,time,type)
	}
}

var book = Book('style','2017','css')

console.log(book);//Book
console.log(book.title);//style

继承

1.类式继承:通过子类的原型prototype对父类实例化来实现


栗子:

//类式继承:子类继承父类
//声明父类
function Father() {
	this.fatherValue = true;
}

//为父类添加公有方法
Father.prototype.getValue = function() {
	return this.fatherValue;
}

//声明子类
function Son() {
	this.sonValue = false;
}

//子类继承父类,特点:将父类原型赋值给子类

Son.prototype = new Father();

//为子类添加共有方法
Son.prototype.getSonValue = function () {
	return this.sonValue;
}

2.构造函数继承:通过子类在构造函数作用环境中执行一次父类的构造函数来实现

//声明父类
function Father(id) {
	//引用类型共有属性
	this.books = ['js','html','css'];
	this.id = id;
}

//父类声明原型方法
Father.prototype.showBooks = function() {
	console.log(this.books);
}

//声明子类
function Son(id) {
	Father.call(this,id);
}

//创建第一个子类的实例
var instance1 = new Son(10);
console.log(instance1.book)

3.混合继承:在子类构造函数中执行父类构造函数,在子类原型上实例化父类

//声明父类

function Father(name) {
	//值类型共有属性
	this.name = name;
	//引用类型共有属性
	this.books = ['css','js','html']
}
//父类原型共有方法
Father.prototype.getName = function() {
	console.log(this.name);
}

//声明子类

function Son(name,time) {
	Father.call(this,name);
	this.time = time;
}

//类似继承,子类原型继承父类
Son.prototype = new Father();
//子类原型方法

Son.prototype.getTime = function() {
	console.log(this.time)
}

var instance1 = new Son('css','js',2017)
console.log(instance1.time)

4.原型式继承 + 寄生式继承

function inheritObject(o) {
	//声明一个过渡函数对象
	function F() {}
	//过渡对象的原型继承父对象
	F.prototype = o;
    //返回过渡向象的一个实例,该实例的原型继承了父对象
	return new F(); 
}

//寄生式继承
//声明基对象
var book = {
	name : 'book',
	alikeBook:["css","js"]
}
function createBook(obj) {
	//通过原型方式创建新对象
	var o = new inheritObject(obj);
	//拓展新对象
	o.getName = function() {
		console.log(name);
	}
	return o;
}

多继承:继承多个对象的属性

//单继承
var extend = function(target,source) {
	//遍历源对象中的属性
	for(var property in source) {
		//将源对象中的属性复制到目标对象中
		target[property] = source[property];
	}
	//返回目标对象
	return target;
}


//多继承 属性复制

var mix = function() {
	var i = 1,//从第二个参数起为被继承的对象
	    len = arguments.length,//获取参数的长度
	    target = arguments[0],//第一个对象为目标对象
	    arg;//缓存参数对象
     //遍历被继承的对象
	for(;i<len;i++) {
		//缓存当前对象
		arg = arguments[i];
		//遍历被继承对象中的属性
		for(var property in arg) {
			//将被继承中的属性复制到目标对象中
			target[property] = arg[property];
		}
	}
	//返回目标对象
	return target;
}

//方法二,绑定到原生对象Object上
Object.prototype.mix = function() {
	var i = 1,//从第一个参数起为被继承的对象
	    len = arguments.length,//获取参数的长度
	    arg;//缓存参数对象
	for(;i<len;i++) {
		//缓存当前对象
		arg = arguments[i];
		//遍历被继承对象中的属性
		for(var property in arg) {
			//将被继承中的属性复制到目标对象中
			target[property] = arg[property];
		}
	}
}


多态:同一个方法多种调用方式

栗子:

function add() {
	var arg = arguments,
	    len = arg.length;
	switch(len) {
		case 0:
		   return 10;
		case 1:
		   return 10 + arg[0];
		case 2:
		   return arg[0] + arg[1];
	}
}

//方式二
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()); 

补充知识:

1、 instanceof 是判断前面的对象是否是后面的类的实例

2、一般称有权访问私有变量和私有函数的公有方法为特权方法

3、 javascript函数级作用域,声明在函数内部的变量以及方法在外界是访问不到的,所以就可以创建私有方法

注意看栗子中的注释




猜你喜欢

转载自blog.csdn.net/caimaomaocai/article/details/80147029