【JavaScript OPP基礎】---新手必備

今天和你們分享一下近期整理的有關JavaScriptOOP的基礎知識~~~咱們一塊兒來學習一下……編程

JavaScriptOOP基礎數組

1、面向對象編程OOP
一、語言的分類:
面向機器:彙編語言
面向過程:C語言
面向對象:C++,Java,PHP等
二、面向過程和麪向對象
①面向過程:專一於如何去解決一個問題的過程。
編程特色:用一個個函數去實現過程操做,沒有類和對象的概念;
②面向對象:專一於有哪個對象實體去解決這個問題。
編程特色是:出現了一個個的類,由類去生成對象。閉包

2、面向對象的三大特徵
繼承,封裝,多態app

3、類&對象的關係
一、類:一羣有相同特徵(屬性)和行爲(方法)的集合
eg: 人類
屬性:"身高,體重,年齡"
方法:"吃飯,睡覺,敲代碼"

二、對象:從類中,new出的具備肯定屬性值和方法的個體稱爲對象。
eg:張三:屬性:身高:身高178,體重150 方法:說話---我叫張三函數

三、類和對象的關係:
類是抽象的,對象是具體的。
!類是對象的抽象化,對象是類的具體化!學習

通俗的來說:
類是一個抽象概念,表示具備相同屬性和行爲的集合。
可是類僅僅表示代表這類羣體具備相同的屬性,可是沒有具體的屬性值。
而對象是對類的屬性進行具體賦值後,而獲得的一個具體的個體;this

eg:人類有身高體重年齡,但不能具體說人類的身高體重具體是多少;而張三是人類的一個具體個體,身高體重等有具體值,則張三就是人類的一個對象。spa

四、使用類和對象的步驟:
①建立一個類(構造函數):
類名,必需要每一個單詞首字母都大寫prototype


function 類名(屬性一){
this.屬性 = 屬性一;
this.方法= function(){}
//this指向誰?即將調用當前構造函數的對象。
}code


②經過類,實例化出一個新的對象;


var obj = new 類名(屬性一Value);
//原構造函數中this,指向新建立的obj對象
obj.方法();調用方法
obj.屬性();調用屬性
實例化對象的時候,會執行構造函數

五、兩個重要屬性:
constructor:返回當前對象的構造函數。(只有對象纔有,返回的是構造函數-類)
>>>zhangsan.constructor == Person
>>>對象的constructor,位於_proto_原型對象上(後續講解)

instanceof:判斷對象是不是某個類的實例
>>>zhangsan instanceof Person true
>>>zhangsan instanceof Object true
>>>Person instanceof Object true(函數也是對象)

六、廣義對象與狹義對象:
廣義對象:除了用字面量聲明的基本數據類型以外,外物皆對象,換句話說,可以添加屬性和方法的變量,就是對象;
var s = "1" ; 不是對象
var s = new String("1") ; 就是對象
狹義對象:只有屬性,方法,除此以外沒有任何東西。
var obj = {}; var obj = new Object();

 

成員屬性與成員方法
1、成員屬性與成員方法
一、在構造函數中經過this.屬性聲明;或者實例化出對象後,經過"對象.屬性"追加的。
都屬於成員屬性,或成員方法;也叫實例屬性與實例方法。

成員屬性/方法,是屬於實例化出的這個對象。
經過"對象.屬性"調用

2、靜態屬性與靜態方法
二、經過"類名.屬性名","類名.方法名"聲明的變量,稱爲靜態屬性,靜態方法;也叫類屬性、類方法。

類屬性/類方法,是屬於類的(屬於構造函數的)
經過"類名.屬性名"調用

三、成員屬性,是屬於實例化出的對象的,會出如今新對象的屬性上
靜態屬性,是屬於類(構造函數)本身的,不會出如今新對象的屬性上

四、JS對象屬性的刪除:
①對象無需手動刪除,JS
②刪除對象的屬性:delete 對象名.屬性名

五、對象是引用數據類型
也就是說,當new出一個對象時,這個obj變量存儲的其實是對象的地址,在對象賦值時,賦的也是地址。
function Person(){}
var xiaoxi = new Person();//xiaoxi對象實際上存的是地址
var ashu = xiaoxi;//賦值時,實際是將xiaoxi存的地址給了ashu
ashu.name = "阿樹";//阿樹經過地址,修改了地址
console.log(xiaoxi.name);//xiaoxi再經過地址打開對象,實際已經變了

引用數據類型,賦值時傳遞的是引用(地址)---快捷方式
基本數據類型,賦值時傳遞的是數據(值)

3、私有屬性和私有方法
六、在構造函數中,經過var聲明的屬性,成爲私有屬性:
function Person(){var num=1;}

私有屬性的做用域,僅在當前函數有效。對外不公開,即經過對象/類都沒法調用到。

原型與原型鏈

【__proto__與prototype】
一、prototype(函數的原型):函數纔有prototype。
prototype是一個對象,指向了當前構造函數的引用地址。
二、__proto__(對象的原型對象):全部對象都有__proto__屬性。當用構造函數實例化(new)一個對象時,
會將新對象的__proto__屬性,指向構造函數的prototype。

eg:zhangsan.__proto__==Person.prototype √

全部對象最終都會指向Object()的prototype。

【原型鏈】
一、經過構造函數,new出的對象,新對象的__proto__指向構造函數的prototype。
二、全部函數的__proto__指向Function()的prototype。
三、非構造函數new出的對象({} new Object() 對象的prototype)的__proto__指向Object的prototype。
四、Object的__proto__指向Null。

原型屬性與原型方法

【類中屬性與方法的聲明方式】
一、成員屬性、成員方法:
this.name = ""; this.func = function(){}
>>>屬於實例化出的對象的。經過"對象.屬性"調用。

二、靜態屬性、靜態方法:
Person.name = ""; Person.func = function(){}
>>>屬於類(構造函數)的。經過"類名.屬性"調用。

三、私有屬性、私有方法:
在構造函數中,使用var num = 1;聲明
>>>只在構造函數內部能用,在外部沒法經過任何方式訪問。

四、原型屬性、原型方法:
Person.prototype.name = "";
Person.prototype.func = function(){};
>>>寫在了構造函數的prototype上,當使用構造函數實例化對象時,該屬性方法會進入新對象的__proto__上。

也就是說,1/4使用對象可訪問,2使用類名可訪問,3只能在函數的{}內使用。

五、習慣上,咱們會將屬性寫爲成員屬性,而方法寫爲原型方法;

eg:

1 function Person(){
2 this.name = "zhangsan";
3 }
4 Person.prototype.say = function(){}

 

緣由:
①實例化出對象後,全部屬性直接在對象上,全部方法都在__proto__上,很是直觀清晰。
②方法寫到prototype上,要更加節省內存。
③使用for in 循環時,會將對象以及對象原型鏈上的全部屬性和方法打印出來,而方法每每是不須要展現的。
將方法寫到__proto__上,可使用hasOwnProperty將原型上的方法更好的過濾。
④官方都這麼寫。

六、當訪問對象的屬性/方法時,會優先使用對象自有的屬性和方法。
若是沒有找到,便使用__proto__屬性在原型上查找,若是找到便可使用。
可是,當對象自身,以及__proto__上有同名方法,執行對象自身的。

七、能夠經過prototype擴展內置函數的相關方法。

代碼演示:

 1 function Person(){
 2 this.name1 = "name1"; //成員屬性
 3 this.age = "age1";
 4 this.sex = "男";
 5 this.say = function(){
 6 alert("我是大帥哥!");
 7 }
 8 var name2 = "name2";//私有屬性
 9 }
10 Person.name3 = "name3";//靜態屬性
11 Person.prototype.name4 = "name4";//原型屬性
12 
13 
14 Person.prototype.say = function(){
15 alert("我叫"+this.name1);
16 }
17 
18 var zhangsan = new Person();
19 //    zhangsan.say = function(){
20 //    alert("我是大帥哥!");
21 //    }
22 zhangsan.say();
23 zhangsan.toString();
24 
25 console.log(zhangsan);
26 
27 //    console.log(zhangsan.name1);
28 //    console.log(zhangsan.name2);
29 //    console.log(zhangsan.name3);
30 //    console.log(zhangsan.name4);
31 //    
32 //    console.log(s);

 

能夠經過prototype擴展內置函數的相關方法

代碼演示:

 1 Number.prototype.add = function(a){
 2 return this+a
 3 }
 4 
 5 var num = new Number(10);
 6 console.log(num);
 7 alert(num.add(3));
 8 
 9 /*
10 * 爲Array類添加一個find(val)方法,當一個Array對象調用該方法的時候,若是能找到val值,則返回其下標,不然返回-1。
11 */
12 Array.prototype.find = function(val){
13 for (var i = 0; i<this.length;i++) {
14 if(this[i]==val){
15 return i;
16 }
17 }
18 return -1;
19 }
20 var arr = new Array(1,2,3,4,5);
21 alert(arr.find(1));

 



位String類添加一個字符串反轉方法

 1 String.prototype.fanzhuan = function(){
 2 var arr = this.split("");
 3 arr.reverse();
 4 return arr.join("")
 5 }
 6 
 7 
 8 console.log(str.fanzhuan());
 9 
10  
11 
12 for-in循環
13 
14 
15for-in循環】
16 for-in循環,主要用於遍歷對象。
17 for()中格式:for(keys in obj){}
18 
19 keys表示obj對象的每個鍵值對的鍵,因此{}中,使用obj[keys]讀取每一個值;
20 可是,使用for-in循環,不但能遍歷對象自己的屬性和方法。還可以遍歷對象原型鏈上的全部屬性和方法。
21 
22 可使用hasOwnProperty判斷一個屬性,是不是對象自身的屬性。
23 obj.hasOwnProperty(keys)==true 表示:keys是對象自身的一個屬性
24 
25 代碼演示:
26 // foreach
27 function Person(){
28 this.name1 = "name11111"; //成員屬性
29 this.age = "age11111";
30 this.func2 = function(){
31 console.log("thisFun")
32 }
33 }
34 Person.name3 = "name333333";
35 Person.prototype.name4 = "name44444";
36 Person.prototype.func1 = function(){
37 console.log("prototypeFun")
38 }
39 var zhangsan = new Person();
40 for(keys in zhangsan){
41 if(zhangsan.hasOwnProperty(keys)){ //過濾掉原型上的屬性,只打印對象自身屬性
42 console.log(zhangsan[keys])
43 }
44 }

 

JS OOP 中的繼承【JS模式實現繼承的三種方式】

【文檔註釋】第一行兩個星號
/**
* ……
*/
調用函數時,能夠看到註釋內容

【JS OOP 中的繼承】
一、使用一個子類繼承另外一個父類,子類能夠自動擁有父類的屬性和方法。

>>>繼承的兩方,發生在兩個類之間。

二、JS模式實現繼承的三種方式:

1)擴展Object實現繼承

①定義父類:function Parent(){}
②定義子類:function Son(){}
③經過原型給Object對象添加一個擴展方法。

1 Object.prototype.customExtend = function(parObj){
2 for(var i in parObj){
3 //經過for-in循環,把父類的全部屬性方法,賦值給本身。
4 this[i] = ParObj[i];
5 }
6 }

 

④子類對象調用擴展方法
son.customExtend(Parent);

2)使用call和apply
首先,瞭解一下call和apply:經過函數名調用方法,強行將函數中的this指向某個對象;
call寫法:func.call(func的this指向的obj,參數1,參數2...);
apply寫法:func.apply(func的this指向的obj,[參數1,參數2...]);
call與apply的惟一區別:在於接收func函數的參數方式不一樣。call採用直接寫多個參數的方式,而apply採用是一個數組封裝全部參數。
①定義父類 funtion Parent(){}
②定義子類 function Son(){}
③在子類中經過call方法或者apply方法去調用父類。
function Son(){
Parent.call(this,....);
}
3)使用原型繼承
①定義父類function Parent(){}
②定義子類function Son(){}
③把在子類對象的原型對象聲明爲父類的實例。
Son.prototype = new Parent();

 

閉包

【JS中的做用域】

一、全局變量:函數外聲明的變量
局部變量:函數內聲明的變量

在JS中,函數爲惟一的局部做用域,而if、for等其餘{}沒有本身的做用域
因此,函數外不能訪問局部變量。
其實,變量在函數執行完畢之後,佔用的內存就被釋放。

二、如何訪問函數私有變量?
JS中,提供了一種"閉包"的概念:在函數內部,定義一個子函數,能夠用子函數訪問父函數的私有變量。執行完操做之後,將子函數經過return返回。

 1 function func2(){
 2 var num = 1;
 3 function func3(){
 4 var sum = num+10;
 5 alert(sum);
 6 }
 7 return func3;
 8 }
 9 var f = func2();
10 f();

 

三、閉包的做用:
① 訪問函數的私有變量;
② 讓函數的變量始終存在於內存中,而不被釋放。


代碼演示:

 1 function func1(){
 2 var n = 1;
 3 }
 4 if(true){
 5 var m = 3;
 6 }
 7 //alert(m); // 3
 8 func1();
 9 //alert(n);// 報錯。函數外不能訪問局部變量。其實,n變量在func1函數執行完畢之後,佔用的內存就被釋放。
10 
11 
12 /*閉包*/
13 function func2(){
14 var num = 1;
15 function func3(){
16 var sum = num+10;
17 alert(sum);
18 }
19 return func3;
20 }
21 var f = func2();
22 f();
23 
24 // 循環轉一次,建立一個lis[i].onclick函數。可是,當點擊li執行函數的時候,i已經變爲6,因此不管點擊哪個,i都是6
25 // 循環建立lis[i].onclick的時候, 循環一次,li[i]裏面的i都被賦爲不一樣值;建立了 li[1] li[2] li[3]...
26 // 可是,建立過程當中,並無執行onlick後面的函數,因此函數裏面的i並無賦值,仍是字母i。
27 // 最終,咱們點擊li[1] li[2]...時,onclick函數裏面的i纔會賦值。(但此時,全局變量的i ,已經成爲6 了)
28 var lis = document.getElementsByTagName("li");
29 for (var i=0;i<lis.length;i++) {
30 lis[i].onclick = function(){
31 //alert("您/點擊了第"+i+"個li!");
32 //console.log(lis[i]);
33 //console.log(this);
34 }
35 }
36 
37 // 循環轉一次,建立一個自執行函數。
38 // 而自執行函數擁有本身的做用域,因此用函數局部做用域j保存當前的全局變量i值。這樣,建立第一個自執行函數,它的j=1;建立第二個,它的j=2...不一樣函數的j互不干擾。
39 // 這樣,循環轉完之後,至關於建立了6個自執行函數,每一個函數中都有一個不一樣的j變量
40 var lis = document.getElementsByTagName("li");
41 for (var i=0;i<lis.length;i++) {
42 !function(){
43 var j = i;
44 lis[j].onclick = function(){
45 alert("您/點擊了第"+j+"個li!");
46 //console.log(lis[i]);
47 //console.log(this);
48 }
49 }();
50 }
51 
52 var lis = document.getElementsByTagName("li");
53 for (var i=0;i<lis.length;i++) {
54 !function(j){
55 lis[j].onclick = function(){
56 alert("您/點擊了第"+j+"個li!");
57 //console.log(lis[i]);
58 //console.log(this);
59 }
60 }(i);
61 }
相關文章
相關標籤/搜索