引言javascript
因爲一些特殊緣由因此,此次就講解下基礎的js插件封裝。java
既然須要封裝,那麼就須要一個封裝的容器,那這個容器是什麼?函數
1.什麼是對象性能
對象就是相似於 類的一個實例 好比同事是一個類,那我身邊的一個同事就是一個對象。this
若是舉個簡單的例子:spa
var a =0;var b = 「javascript」;var c = [1,2,3];var d = { key:11,value:22}
這些都是一個對象,可是光有對象還不行,還須要有構造。prototype
2.什麼是構造函數插件
簡單說構造函數是類函數,函數名與類名徹底相同,且無返回值。構造函數是類的一個特殊成員函數。指針
js建立構造的幾種方式:code
1.工廠模式
考慮到在 ECMAScript 中沒法建立類,開發人員就發明了一種函數,用函數來封裝以特定接口建立對象的細節,以下面的例子所示:
function createPerson(id,name){ var o = new Object(); o.id = id; o.name = name; o.sayName = function(){ alert(this.name); } return o; } var person1 = createPerson(1,27);
函數 createPerson()可以根據接受的參數來構建一個包含全部必要信息的 Person 對象。能夠無數次地調用這個函數,而每次它都會返回一個包含三個屬性一個方法的對象。工廠模式雖然解決了建立\多個類似對象的問題,但卻沒有解決對象識別的問題(即怎樣知道一個對象的類型)。
主要好處就是能夠消除對象間的耦合,經過使用工程方法而不是new關鍵字。將全部實例化的代碼集中在一個位置防止代碼重複。
工廠模式解決了重複實例化的問題 ,但還有一個問題,那就是識別問題,由於根本沒法 搞清楚他們究竟是哪一個對象的實例。
2.構造函數模式
ECMAScript中的構造函數可用來建立特定類型的對象,像Array和Object這樣的原生構造函數,在運行時會自動出如今執行環境中。此外,也能夠建立自定義的構造函數,從而定義自定義對象的屬性和方法。使用構造函數的方法,既解決了重複實例化的問題,又解決了對象識別的問題。例如,可使用構造函數模式將前面的例子重寫以下:
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); } } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person('Grey',27,'Doctor');
Person()中的代碼除了與 createPerson()中相同的部分外,還存在如下不一樣之處:
沒有顯式地建立對象;
直接將屬性和方法賦給了 this 對象;
沒有 return 語句。
3.原型模式
咱們建立的每一個函數都有一個 prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含能夠由特定類型的全部實例共享的屬性和方法。
若是按字面意思來理解,那麼prototype就是經過調用構造函數而建立的那個對象實例的原型對象。使用原型對象的好處是可讓全部對象實例共享它所包含的屬性和方法。換句話說,沒必要在構造函數中定義對象實例的信息,而是能夠將這些信息直接添加到原型對象中。例如:
function Person(){ } Person.prototype.name = 'Nicholas'; Person.prototype.age = 29; Person.prototype.job = 'Software Engineer'; Person.prototype.sayName = function(){ alert(this.name); } var person1 = new Person(); person1.sayName();//"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true
在此,咱們將 sayName()方法和全部屬性直接添加到了 Person 的 prototype 屬性中,構造函數變成了空函數。
即便如此,也仍然能夠經過調用構造函數來建立新對象,並且新對象還會具備相同的屬性和方法。但與構造函數模式不一樣的是,新對象的這些屬性和方法是由全部實例共享的。換句話說,person1 和 person2 訪問的都是同一組屬性和同一個 sayName()函數。要理解原型模式的工做原理,必須先理解 ECMAScript 中原型對象的性質。
3 繼承
既然要實現繼承,那麼首先咱們得有一個父類,代碼以下:
// 定義一個動物類 function Animal (name) { // 屬性 this.name = name || 'Animal'; // 實例方法 this.sleep = function(){ console.log(this.name + '正在睡覺!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); };
核心: 將父類的實例做爲子類的原型
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.eat('fish')); console.log(cat.sleep()); console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true
特色:
缺點:
new Animal()
這樣的語句以後執行,不能放到構造器中核心:使用父類的構造函數來加強子類實例,等因而複製父類的實例屬性給子類(沒用到原型)
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
特色:
缺點:
核心:爲父類實例添加新特性,做爲子類實例返回
function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false
特色:
new 子類()
仍是子類()
,返回的對象具備相同的效果缺點:
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
特色:
缺點:
核心:經過調用父類構造,繼承父類的屬性並保留傳參的優勢,而後經過將父類實例做爲子類原型,實現函數複用
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true
特色:
缺點:
核心:經過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){ // 建立一個沒有實例方法的類 var Super = function(){}; Super.prototype = Animal.prototype; //將實例做爲子類的原型 Cat.prototype = new Super(); })(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true Cat.prototype.constructor = Cat; // 須要修復下構造函數
特色:
缺點: