#JS面向對象及組件開發
###面向對象編程的特點
抽象:抓住核心問題
封裝:只能通過對象來訪問方法
繼承:從已有對象上繼承出新的對象
多態:多對象的不同形態
###工廠方式與構造函數
```
function CreatePerson(name){
var obj = new Object();
obj.name = name;
obj.showName = function(){
alert(this.name);
};
return obj;
}
var p1 = new CreatePerson('小明');
p1.showName();
var p2 = new CreatePerson('小強');
p2.showName();
```
當new去調用一個函數:這個時候函數中的this就是創建出來的對象,而且函數的返回值直接就是this(隱式返回),也就是說最后一句 return obj 可以不寫。上面的函數可以優化成如下:
```
function CreatePerson(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
var p1 = new CreatePerson('小明');
p1.showName();
var p2 = new CreatePerson('小強');
p2.showName();
```
new后面調用的函數:叫做構造函數
###對象引用是什么和它的問題
```
function CreatePerson(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
var p1 = new CreatePerson('小明');
var p2 = new CreatePerson('小強');
alert(p1.showName == p2.showName); // false
```
```
var a = [1,2,3];
var b = [1,2,3];
alert(a == b); //false
```
```
var a = 5;
var b = a;
b += 3;
alert(b); // 8
alert(a); // 5 基本類型:賦值的時候只是值的復制
```
```
var a = [1,2,3];
var b = a;
b.push(4);
alert(b); // 1,2,3,4
alert(a); // 1,2,3,4 對象類型:賦值不僅是值的復制,而且也是引用的傳遞
```
```
var a = [1,2,3];
var b = a;
b = [1,2,3,4]; // 賦值操作會在內存中新開一塊空間
alert(b); // 1,2,3,4
alert(a); // 1,2,3
```
```
var a=5;
var b=5;
alert(a == b); // 基本類型:值相同就為真
```
```
var a = [1,2,3];
var b = [1,2,3];
alert(a==b); //false 對象類型:值和引用都相同才為真
```
```
var a = [1,2,3];
var b = a;
alert(a==b); //true
```
這就是為什么 p1.showName == p2.showName 為false的原因, 每次new都會創建一個對象,都會在內存中新開一塊空間。雖然兩次創建的對象都有一個showName方法,但他們的引用地址卻是不相同的,所以為false。那么這個false和true對我們這個程序有什么影響呢?我們現在是創建了兩個對象,那么如果我們創建了200個對象或者說2000對象,那么showName是不是在內存中就存在200或者說2000份,這樣的話就會極大的消耗內存。如果說讓它為真的話,也就是說值相同而且引用也相同,引用相同就說明showName方法在內存中只有一份,怎么樣讓這個地方變成true呢,讓內存中同樣的方法只存在一份,這就是接下來要說的一個東西 - 原型。
原型:原型的作用就是去改寫對象下面公用的方法或者屬性,讓公用的方法或者屬性在內存中只存在一份,這樣就可以提高性能
###面向對象之原型學習
```
// arr1數組求和
var arr1 = [1, 2, 3, 4, 5];
arr1.sum = function () {
var result = 0;
for (var i = 0; i < this.length; i++) {
result += this[i];
}
return result;
};
alert(arr1.sum()); // 15
// arr2數組求和
var arr2 = [2, 3, 4, 5, 6];
arr2.sum = function () {
var result = 0;
for (var i = 0; i < this.length; i++) {
result += this[i];
}
return result;
};
alert(arr2.sum()); // 20
```
用原型改寫:
```
// 原型:prototype:要寫在構造函數的下面
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [2, 3, 4, 5, 6];
Array.prototype.sum = function () {
var result = 0;
for (var i = 0; i < this.length; i++) {
result += this[i];
}
return result;
};
alert(arr1.sum()); // 15
alert(arr2.sum()); // 20
```
普通方式與原型的優先級 (普通方式的優先級高)
```
var arr = [];
arr.number = 10;
Array.prototype.number = 20;
alert(arr.number); // 10
```
用原型方式改造之前用工廠方式寫的方法
```
function CreatePerson(name){
this.name = name;
}
CreatePerson.prototype.showName = function(){
alert(this.name);
};
var p1 = new CreatePerson('小明');
var p2 = new CreatePerson('小強');
alert(p1.showName == p2.showName); // true
p1.showName(); // 小明
p2.showName(); // 小強
alert(p1.name); // 小明
alert(p2.name); // 小強
```
面向對象寫法總結:公用的東西就可以寫在原型上面,比如像上面例子中的showName方法。但是,它的name屬性是變化的,就不適合寫在原型上面。暫時使用下面混編的方式來練習面向對象寫法
```
function 構造函數(){
this.屬性
}
構造函數.原型.方法 = function(){};
var 對象1 = new 構造函數();
對象1.方法()
```
- 01 JS面向對象及組件開發
- 02 傳統的過程式編寫選項卡
- 03 用面向對象封裝通用選項卡
- 04 控制多個選項卡自動播放
- 05 用面向對象編寫拖拽
- 06 JS面向對象及組件開發
- 07 hasOwnProperty和constructor的使用
- 08 instanceof運算符的使用
- 09 利用toString做類型判斷
- 10 什么是面向對象的繼承
- 11 面向對象之拷貝繼承
- 12 編寫繼承的拖拽
- 13 繼承的其他形式之類式繼承
- 14 繼承的其他形式之原型繼承
- 15 組件開發是什么
- 16 給拖拽組件配置不同參數
- 17 封裝彈框組件
- 18 使用對象標記已彈出彈框
- 19 復雜組件開發之自定義事件
- 20 原生JS實現自定義事件
- 21 自定義事件實例
- 22 基于JQ的選項卡組件開發