面向对象编程就是将你的需求抽象成一个对象,然后针对这个对象分析其特性(属性)与动作(方法)。
面向对象思想:对一些属性方法的隐藏与暴露,比如私有属性、私有方法、共有属性、共有方法
栗子:
//创建一个类 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函数级作用域,声明在函数内部的变量以及方法在外界是访问不到的,所以就可以创建私有方法
注意看栗子中的注释