前 言前端
Javascript是一種基於對象(object-based)的語言,你遇到的全部東西幾乎都是對象。可是,它又不是一種真正的面向對象編程(OOP)語言,由於它的語法中沒有class(類)。面向對象主要專一於有哪個對象來解決這個問題,編程特色時出現一個個的類,從類中拿到對象,有這個對象去解決具體問題。 對於調用者來講,面向過程須要調用者去實現各類函數。而面向對象,只須要告訴調用者對象中的具體方法的功能, 而不須要調用者瞭解方法中的實現細節。編程
而面向過程主要專一於如何去解決一個問題的步驟。編程特色是由一個個的函數去實現每一步的過程步驟,沒有類和對象的概念。app
1、 繼承 |
咱們首先解釋一下繼承的概念,所謂繼承就是使用一個子類,繼承另外一個父類,那麼子類能夠自動擁有父類中的全部屬性和方法,這個過程叫繼承,繼承的兩方,發生在兩個類間。函數
而後咱們闡述一下實現繼承的原理, 經過循環將父類對象的全部屬性,所有賦給子類對象。關鍵點在於for-in循環, 即便不擴展循環Object,也能經過簡單的循環實現操做
學習
1 function Person(name,age){ 2 this.name=name; 3 this.age=age; 4 this.say=function(){ 5 alert("我叫"+this.name); 6 } 7 } 8 9 function Student(no){ 10 this.no=no; 11 this.study=function(){ 12 alert("我在學習"); 13 } 14 } 15 16 var p=new Person("張三",12); 17 var s=new Student("12345"); 18 for(var i in p){ 19 s[i]=p[i]; 20 } 21 22 Object.prototype.extend1=function(){ 23 for(var i in parent){ 24 this[i]=parent[i]; 25 } 26 } 27 s.extend1(p); 28 29 console.log(s);
可是呢,擴展Object繼承也有以下缺點:
① 沒法經過一次實例化,拿到完整的子類對象,而須要先拿到父類對象和子類對象兩個對象,手動合併
② 擴展Object繼承方法,也會保留在子類對象上this
咱們先說說使用原型繼承的原理, 將父類對象,賦值給子類的prototype,那麼父類對象的屬性和方法就會出如今子類的prototype中。 那麼,實例化子類時,子類的prototype又不會到子類對象的__proto__中, 最終,父類對象的屬性和方法,會出如今子類對象的__proto__spa
這種繼承的特色主要是,子類自身的全部屬性,都是成員屬性,父類繼承過來的屬性,都是原型屬性,可是依然沒法經過一次實例化拿到全部的子類對象。prototype
1 function Person(name,age){ 2 this.name=name; 3 this.age=age; 4 this.say=function(){ 5 alert("我叫"+this.name); 6 } 7 } 8 9 function Student(no){ 10 this.no=no; 11 this.study=function(){ 12 alert("我在學習"); 13 } 14 } 15 16 Student.prototype=new Person("張三",12); 17 var s=new Student(15); 18 console.log(s);
咱們先解釋一下call/bind/apply三個函數的做用,這三個函數經過函數名調用這三個函數,能夠強行將函數中的this指定爲某個對象。code
1 var name="window" 2 function func(a,b){ 3 console.log(this.name+a+b); 4 } 5 var obj={ 6 name:"zhangsan" 7 } 8 var obj1={ 9 name:"lisi" 10 } 11 func(1,2);//window12 12 func.call(obj,1,2);//zhangsan12 13 func.apply(obj1,[1,2]);//lisi12 14 func.bind(obj)(1,2);//zhangsan12 15 16 17 function Person(name,age){ 18 this.name=name; 19 this.age=age; 20 this.say=function(){ 21 alert("我叫"+this.name); 22 } 23 } 24 25 function Student(no,name,age){ 26 this.no=no; 27 this.study=function(){ 28 alert("我在學習"); 29 } 30 Person.call(this,name,age); 31 } 32 var s=new Student(12345,"張三",15); 33 console.log(s);
這三個函數的惟一區別,在於接受func參數列表的方式不一樣,除此以外,功能上無區別。對象
2、 封裝 |
什麼叫封裝呢?封裝分爲方法的封裝和屬性的封裝。
所謂 方法的封裝就是將類內部的函數進行私有化處理,不對外提供調用接口,沒法在類外部使用的方法,稱爲私有方法,即方法的封裝。
而屬性的封裝: 將類中的屬性進行私有化處理,對外不能直接使用對象名訪問(私有屬性)。 同時,須要提供專門用於設置和讀取私有屬性的set/get方法,讓外部使用咱們提供的方 法,對屬性進行操做。 這就叫屬性的封裝。
封裝也有須要 注意的地方, 封裝不是拒絕訪問,而是限制訪問。 要求調用者,必須使用咱們提供的set/get方法進行屬性的操做,而不是直接拒絕操做。
所以,單純的屬性私有化,不能稱爲封裝!必需要私有化以後,提供對應的set/get方法。
一、 生成實例對象的原始模式 |
1 var Person={ 2 3 name : "張三", 4 5 age : "12" 6 7 }
1 var Person1= {}; // 建立一個空對象 2 Person1.name = "張三"; // 按照原型對象的屬性賦值 3 Person1.age= "12"; 4 var Person2= {}; 5 Person2.name = "李四"; 6 Person2.age= "15"; 7 8 //這就是最簡單的封裝了,把兩個屬性封裝在一個對象裏面。
二、 原始對象模式的改進 |
1 function Person(name,age) { 2 return { 3 name:name, 4 age:age 5 } 6 } 7 8 var Person1= Person("張三","12"); 9 var Person2= Person("李四","15");
三、 構造函數 |
構造函數:其實就是一個普通函數,可是內部使用了this變量。對構造函數使用new
運算符,就能生成實例,而且this
變量會綁定在實例對象上。
咱們來講說建立一個類和對象的大概步驟,
首先,建立一個類(構造函數):類名必須使用大駝峯法則。即每一個單詞首字母大寫。
function 類名(屬性1){
this.屬性1=屬性1;
this.方法=function(){
//方法中要調用自身屬性,必須使用this.方法
}
}
經過類,實例化(new)出一個對象。
var obj=new 類名(屬性1的具體值);
obj.屬性; //調用屬性
obj.方法(); //調用方法
1 //人的原型對象 2 function Person(name,age){ 3 this.name=name; 4 this.age=age; 5 } 6 7 //生成實例對象 8 var Person1= new Person("張三","12"); 9 var Person2= new Person("李四","15"); 10 console.log(Person1.name); // 張三 11 console.log(Person2.age); // 15 12 13 //Person1 和 Person2都會有一個constructor屬性,返回當前對象的構造函數 14 console.log(Person1 .constructor == Person); //true 15 console.log(Person2 .constructor == Person); //true 16 17 //instanceof檢測一個對象是否是一個類的實例 18 console.log(Person1 instanceof Person); //true 19 console.log(Person2 instanceof Person); //true
構造函數須要注意如下幾點,
一、經過一個類名,new出一個對象的過程,叫作"類的實例化"
二、類中的this,會在實例化的時候指向新的new出的對象
因此,this.方法this.屬性,其實是將屬性和方法綁定在即將new出的對象上,在類中調用自身屬性,必須使用this.屬性名。若是直接使用變量名,則沒法訪問對應的屬性。 類名必須使用大駝峯法則,注意區分與普通函數的區別。
四、 Prototype模式 |
prototype 屬性容許您向對象添加屬性和方法,每個構造函數都有一個prototype
屬性,指向另外一個對象。這個對象的全部屬性和方法,都會被構造函數的實例繼承。
1 function Person(name,age){ 2 this.name=name; 3 this.age=15; 4 } 5 Person.prototype.age=12; 6 var zhangsan=new Person("張三"); 7 console.log(zhangsan.age);
Javascript面向對象是最難的,初學者不容易掌握,能夠多多參考參考專門Javascript面向對象的資料,最後,但願各位和小編一塊兒努力,在前端的路上越走越遠!