[toc]
## 基于面向對象創建數據值
### 引用數據類型的兩種創建方式
數組
```
var ary = [12,23]; //=>字面量創建方式
var ary = new Array(); //=>嚴謹的基于面向對象(構造函數)方式創建一個數組
/**
* 兩種創建方式在核心意義上沒有差別,都是創建Array這個類的一個實例,但是在語法上有區別的
* 1、 字面量創建方式傳遞進來什么,都是給數組每一項加入的內容
* 2、 實例創建方式(構造函數創建方式)
* new Array(10):創建一個長度為10的數組,數組中的每一項都是空
* new Array('10'):如果只傳遞一個實參,并且實參不是數字,相當于把當前值作為數組的第一項存儲進來
* new Array('10','20','30'):如果傳遞多個實參,不是設置長度,而是把傳遞的內容當做數組中的每一項存儲起來
*/
```
對象
```
var obj = {name:'克麗絲'};
var obj = new Object({name:'克麗絲'}); //沒意義 //我們一般用new的方式創建空對象
var obj = {name:'克麗絲'};
var obj2 = new Object(obj);
obj2 === obj;
```
### 基本數據類型的兩種創建方式
```
//=>字面量創建出來的是一個基本數據類型值(但也是Number的一個實例,可以調取Number賦予它的方法)
var num = 12
typeof num => number
//=>構造函數方式創建出來的也是Number的一個實例(也可以使用Number賦予它的方法),但是獲取的結果是對象數據類型的
var num = new Number(12);
typeof num => object
```
通過字面量創建出來的實例是基本類型的值,這體現了JS的松散型(嚴謹的面向對象只能通過new的方式)
兩種方式創建出來的都是類的實例
,當一個通過字面量創建的數據想要調用一個方法時,基本類型會變成一個真正的實例對象,再調用類上的方法
### 構造函數設計模式(constructor)
使用構造函數方式,主要是為了創建類和實例,也就是基于面向對象編程思想來實現一些需求的處理
在JS中,當我們使用`new xxx()`執行函數的時候,此時的函數就**不是普通的函數了**,而是變為一個**類**,返回的結果叫做當前類的實例,我們把這種`new xxx`執行的方式稱之為`構造函數設計模式`。
```
function fn(){
}
fn();
//加了new 就不再是普通函數運行
var f = new fn(); //不一定要大寫,只是不夠嚴謹,最好還是將類名的第一個字母大寫
//f是當前這個類的一個實例
```
#### 普通函數執行 VS 構造函數執行
構造函數執行,即具備普通函數執行的一面,也同時具備自己獨有的一些操作。
在構造函數執行期間,瀏覽器默認創建的對象(也就是函數體中的this),代表的就是當前這個類的一個實例,瀏覽器會把默認創建的實例返回,所以我們說:new Fn()執行,Fn是一個類,返回的結果是Fn這個類的一個實例。
>普通函數執行
>1、 開辟一個新的私有作用域
>2、 形參賦值
>3、 變量提升
>4、 代碼自上而下執行(return后面的值就是當前函數返回的結果)
>5、 棧內存釋放或則不釋放
```
function fn(num){
this.num = num; //this=>window 給全局對象增加一個num的屬性名,屬性值是10
var total = null;
total += num;
return total;
}
var f = fn(10); //=>f:10
```
>構造函數執行
>1、首先和普通函數一樣,也需要開辟一個新的私有作用域
>2、 在私有作用中完成類似于普通函數的操作:形參賦值以及變量提升
>3、 在代碼自上而下執行之前,構造函數有屬于自己比較特殊的操作:瀏覽器會在當前作用域中默認創建一個對象數據類型的值,并且會讓當前函數中的執行主體(this)指向創建的這個對象
>4、 向普通函數一樣,代碼自上而下執行:當遇到this.xxx = xxx 這里的操作都是在給瀏覽器幫我們創建的這個對象增加屬性名和屬性值
>5、 代碼執行完成后,即使函數中沒有寫return,在構造函數模式中:瀏覽器會默認把創建的對象返回到函數外面
```
function Fn(num){
//this的第四種情況
//=>在構造函數模式中,方法體中出現的THIS是當前類的一個實例(this.xxx = xxx都是在給當前實例增加一些私有的屬性)
this.num = num;
}
var f = new Fn(10);
```
#### 深入理解構造函數執行的步驟
>當構造函數或則類,執行的時候不需要傳遞任何的實參值,此時我們是否加小括號就不重要了。(不傳遞實參的情況下,小括號可以省略)
>
>構造函數執行,同時具備了普通函數執行的一面,也有自己特殊的一面,但是和實例相關的,只有自己特殊的一面才相關(也就是this.xxx=xxx才相當于給當前實例增加了私有屬性),函數體中出現的**私有變量**,和實例都**沒有**直接的關系
>
>通過類創建出來的每一個實例都是單獨的個體(單獨的堆內存空間),實例和實例之間是不相同并且獨立互不影響的。(市面上部分開發把這種模式叫做單例模式,這種說法是不確切的,JS中的這種模式叫做構造函數設計模式)
>
>在構造函數體中,通過this.xxx給實例設置的屬性都是當前實例的私有屬性
```
function Fn(){
var num = 111;
this.name = 'ahh';
this.sum = function(){}
}
var f1 = new Fn();
var f2 = new Fn();
f1.num //->undefined
f1.name //->ahh
//=>不同實例是不同的空間地址
f1===f2; //false
f1.sum === f2.sum; //false
```

##### 關于return
>當構造函數體中我們自己手動設置了`return`(默認返回的是實例:對象類型值),return的值是一個基本類型值,對最后返回的實例沒有任何的影響,但是如果返回的是引用數據類型的值,會把默認返回的實例替換掉。
```
function Fn(){
this.name = 'ahhh';
return 1
}
var f = new Fn(); //f =1
function Fn(){
this.name = 'ahhh';
return {name:'xxx'}
}
var f = new Fn(); //=>f不再是Fn的實例,而是變為手動返回的對象了
```
#### instanceof
>用來檢測當前實例是否隸屬于某個類
```
function Fn(){}
var f = new Fn;
console.log(f instanceof Fn); //=>true
```
>instanceof解決了typeof無法識別是數組還是其他引用類型數據的問題
```
[] instanceof Array //=>true
/^$/ instanceof Array //=>false
```
>所有對象數據類型的都是`Object`類的實例(最終都會`__proto__`指向Object.prototype)
#### hasOwnProperty VS in
in:用來檢測當前這個屬性是否隸屬于對象(不管對象是私有的還是公有的屬性,只要有返回就是true)
hasOwnProperty:檢測當前屬性是不是屬于當前對象的私有屬性(不僅要是對象的屬性,而且需要是私有的才可以,或則說自己有但祖先也有)
```javascript
var obj = {name:'ahhh',age:111};
'name' in obj; //=>true
'toString' in obj; //=>true
'hasOwnProperty' in obj; //=>true
//hasOwnProperty是object這個內置類中提供的屬性方法,只要當前對象是Object的一個實例,就可以使用這個方法
obj.hasOwnProperty('hasOwnProperty'); //=>false
obj.hasOwnProperty('name'); //=>true
```
>檢測一個屬性是否是當前對象的公有屬性
>1、 是對象的一個屬性
>2、 不是對象的私有屬性
```
function isAncestorProperty(attr,obj){
return (attr in obj)&&(!obj.hasOwnProperty(attr));
}
```
- 空白目錄
- window
- location
- history
- DOM
- 什么是DOM
- JS盒子模型
- 13個核心屬性
- DOM優化
- 回流與重繪
- 未整理
- 文檔碎片
- DOM映射機制
- DOM庫封裝
- 事件
- 功能組件
- table
- 圖片延遲加載
- 跑馬燈
- 回到頂部
- 選項卡
- 鼠標跟隨
- 放大鏡
- 搜索
- 多級菜單
- 拖拽
- 瀑布流
- 數據類型的核心操作原理
- 變量提升
- 閉包(scope)
- this
- 練習題
- 各種數據類型下的常用方法
- JSON
- 數組
- object
- oop
- 單例模式
- 高級單例模式
- JS中常用的內置類
- 基于面向對象創建數據值
- 原型和原型鏈
- 可枚舉和不可枚舉
- Object.create
- 繼承的六種方式
- ES6下一代js標準
- babel
- 箭頭函數
- 對象
- es6勉強筆記
- 流程控制
- switch
- Ajax
- eval和()括號表達式
- 異常信息捕獲
- 邏輯與和或以及前后自增
- JS中的異步編程思想
- 上云
- 優化技巧
- 跨域與JSONP
- 其它跨域相關問題
- console
- HTML、XHTML、XML
- jQuery
- zepto
- 方法重寫和方法重載
- 移動端
- 響應式布局開發基礎
- 項目一:創意簡歷