封裝類javascript
var Book = function (id, bookname, price) { this.id = id; this.bookname = bookname; this.price = price;};
類的原型css
Book.prototype = { display: function () { console.log("展現這本書"); }};
constructor 屬性返回對建立此對象的數組函數的引用html
var book = new Book(10, 'javascript設計模式', 50);console.dir(Book); console.dir(Book.prototype.constructor);//Book Object console.log(book);
面向對象思想 私有屬性 私有方法 共有屬性 保護方法 ...java
//私有屬性與私有方法,特權方法,對象共有屬性和對象共有方法,構造器 var BookTwo = function (id, name, price) { //私有屬性 var num = 1; //私有方法 function checkId() { console.log(this.id); } //特權方法 this.getName = function () { return this.name; }; this.getPrice = function () { return this.price; }; this.setName = function (name) { this.name = name; }; this.setPrice = function (price) { this.price = price; }; //對象公有屬性 this.id = id; //對象公有方法 this.copy = function () { console.log('copy'); }; //構造器 this.setName(name); this.setPrice(price);}; //類靜態公有屬性(對象不能訪問) BookTwo.isChinese = true;//類靜態公有方法(對象不能訪問) BookTwo.resetTime = function () { console.log('new Tiem'); }; BookTwo.prototype = { //公有屬性 isJSBook: false, //公有方法 display: function () { console.log("顯示"); }}; var booktwo = new BookTwo(11, 'javascript設計模式', 50); console.log(booktwo); console.log(booktwo.num);//undefined console.log(booktwo.isJSBook);//false booktwo.display();//顯示 console.log(booktwo.id);//11 console.log(booktwo.isChinese);//undefined //類的靜態公有屬性能夠經過類的自身訪問 console.log(BookTwo.isChinese);//true BookTwo.resetTime();//new Time
類的靜態變量 經過閉包來實現ajax
//利用閉包來實現 var BookThree = (function () { //靜態私有變量 var bookNum = 0; //靜態私有方法 function checkBook(name) { console.log(name); } //構造函數 function _book(newId, newName, newPrice) { //私有變量 var name, price; //私有方法 function checkID(id) { } //特權方法 this.getName = function () { return this.name; }; this.getPrice = function () { return this.price; }; this.setName = function (name) { this.name = name; }; this.setPrice = function (price) { this.price = price; }; //公有屬性 this.id = newId; //公有方法 this.copy = function () { }; bookNum++; if (bookNum > 100) { throw new Error('咱們僅出版100本書'); } //構造器 this.setName(newName); this.setPrice(newPrice); } return _book; })(); var bookThree = new BookThree(11, 'javascript設計模式', 50); console.log(bookThree);
建立對象的安全模式-去除 new 也可成功事例化對象設計模式
var BookFour = function (id, name, price) { this.id = id; this.name = name; this.price = price;}; var bookFour = BookTwo(12, 'javascript設計模式', 50);console.log(bookFour);//undefined console.log(window.id);//12 console.log(window.name);//javascript設計模式 console.log(window.price);//50 bookFour = new BookTwo(13, 'javascript設計模式', 50);console.log(bookFour); //圖書安全類 /* * instanceof 運算符用來判斷一個構造函數的prototype屬性所指向的對象是否存在另一個要檢測對象的原型鏈上 * */var BookFive = function (id, name, price) { //判斷執行過程當中的this是不是當前對象(若是是說明是new建立的) if (this instanceof BookFive) { this.id = id; this.name = name; this.price = price; } else {//從新建立這個對象 return new BookFive(id, name, price); }}; //都能成功建立 var bookFive = BookFive(14, 'javascript設計模式', 50); console.log(bookFive); bookFive = new BookFive(15, 'javascript設計模式', 50); console.log(bookFive);
類式繼承 - 關鍵:SubClass.prototype = new SuperClass();數組
//聲明父類 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.getSuperValue()); console.log(instance.getSubValue()); /* * instance 判斷對象和類之間的繼承關係 實例-》類 * * 是判斷 實例 與 類 的繼承關係 * */console.log(instance instanceof SuperClass);//true console.log(instance instanceof SubClass);//true console.log(SubClass instanceof SuperClass);//false console.log(SubClass.prototype instanceof SuperClass);//true console.log(instance instanceof Object);//true
類式的缺點緩存
function SuperClassTwo() { this.books = ['Javascript', 'html', 'css'];} function SubClassTwo() { } SubClassTwo.prototype = new SuperClassTwo(); var instance1 = new SubClassTwo(); var instance2 = new SubClassTwo(); console.log("類式的缺點"); console.log(instance1.books);//["Javascript", "html", "css"] instance1.books.push('設計模式'); console.log(instance2.books);//["Javascript", "html", "css", "設計模式"]
總結:在修改instance1的時候instance2也被修改了這樣會形成程序的錯誤安全
//構造函數式繼承 //聲明父類 function SuperClassThree(id) { //引用類型共有屬性 this.books = ['Javascript', 'html', 'css']; //值類型共有屬性 this.id = id;} //父類聲明原型方法 SuperClassThree.prototype.showBooks = function () { console.log(this.books); }; //聲明子類 function SubClassThree(id) { //繼承父類 SuperClassThree.call(this, id); } //建立第一個子類的實例 var instance3 = new SubClassThree(10); //建立第一個子類的實例 var instance4 = new SubClassThree(11); instance3.books.push("設計模式"); console.log(instance3.books);//["Javascript", "html", "css", "設計模式"] console.log(instance3.id);//10 console.log(instance4.books);//["Javascript", "html", "css"] console.log(instance4.id);//11
將優勢爲我所用--組合繼承閉包
//組合繼承 //聲明父類 function SuperClassFour(name) { //值類型共有屬性 this.name = name; //引用類型共有屬性 this.books = ['html', 'css', 'Javascript']} //父類原型共有方法 SuperClassFour.prototype.getName = function () { console.log(this.name); }; //聲明子類 function SubClassFour(name, time) { //構造函數式繼承父類name屬性 SuperClassFour.call(this, name); //子類中新增共有屬性 this.time = time;} //類式繼承 子類原型繼承父類實例 SubClassFour.prototype = new SuperClassFour(); //子類原型方法 SubClassFour.prototype.getTime = function () { console.log(this.time); }; console.log('將優勢爲我所用--組合繼承'); var instance5 = new SubClassFour('js book', 2014); console.log(instance5); instance5.books.push('設計模式'); console.log(instance5.books); instance5.getName(); instance5.getTime(); var instance6 = new SubClassFour('css book', 2013); console.log(instance6.books); instance6.getName(); instance6.getTime();
同時沒必要建立新的自定義對象類型
function inheritObject(o) { //聲明一個過濾函數對象 function F() { } //過濾對象的原型繼承父對象 F.prototype = o; //返回過渡對象的一個實例,改實例的原型繼承了父隊象 return new F(); } var book5 = { name: 'js book', alikeBook: ['css book', 'html book'] }; var newBook = inheritObject(book5); newBook.name = 'ajax book';newBook.alikeBook.push('xml book'); var otherBook = inheritObject(book5); otherBook.name = 'flash book';otherBook.alikeBook.push('as book'); console.log(newBook.name); //ajax book console.log(newBook.alikeBook);//["css book", "html book", "xml book", "as book"] console.log(otherBook.name);//flash book console.log(otherBook.alikeBook);// ["css book", "html book", "xml book", "as book"] console.log(book5.name);//js book console.log(book5.alikeBook);//["css book", "html book", "xml book", "as book"]
如虎添翼--寄生式繼承
//寄生式繼承 //聲明基對象 var book6 = { name: 'js book', alikeBook: ['css book', 'html book'] }; //原型式繼承 function inheritObjectTwo(o) { //聲明一個過濾函數對象 function F() { } //過濾對象的原型繼承父對象 F.prototype = o; //返回過渡對象的一個實例,改實例的原型繼承了父隊象 return new F(); } function createBook(obj) { console.log(obj); //經過原型繼承方式建立新對象 var o = inheritObjectTwo(obj); console.log(o.name); //拓展新對象 o.getName = function () { console.log(this.name); }; //返回拓展後的新對象 return o;} var book7 = createBook(book6); console.log(book7.getName);
終極繼承者
/* * 寄生式繼承 繼承原型 * 傳遞參數 subClass 子類 * 傳遞參數 superClass 父類 * constructor 屬性返回對建立此對象的數組函數的引用。 * */function inheritPrototype(subClass, superClass) { //複製一份父類的原型副本保存在變量中 var p = inheritObject(superClass.prototype); //修正由於重寫子類原型致使子類的constructor屬性被修改 p.constructor = subClass; //設置子類的原型 subClass.prototype = p;} //定義父類 function ParentClass(name) { this.name = name; this.colors = ['red', 'blue', 'green']} //定義父類原型方法 ParentClass.prototype.getName = function () { console.log(this.name); }; //定義子類 function ChildClass(name, time) { //構造函數式繼承 ParentClass.call(this, name); //子類新增屬性 this.time = time;} //寄生式繼承父類原型 inheritPrototype(ChildClass, ParentClass); //子類新增原型方法 ChildClass.prototype.getTime = function () { console.log(this.time); }; //建立兩個測試方法 var test1 = new ChildClass('js book', 2014); var test2 = new ChildClass('css book', 2013); test1.colors.push('black'); console.log(test1.colors);//["red", "blue", "green", "black"] console.log(test2.colors);//["red", "blue", "green"] test2.getName();//css book test2.getTime();//2013
老師不止一位--多繼承
// 單繼承 屬性複製 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 = 0, len = arguments.length, arg; for (; i < len; i++) { //緩存當前對象 arg = arguments[i]; //遍歷被繼承對象中的屬性 for (var property in arg) { //將被繼承對象中的屬性複製到目標對象中 this[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]; }}