JavaScript筆記(對象)

1 對象類型

JavaScript語言中的對象可分爲三種類型:javascript

  • 用戶定義對象(user-defined object):由程序員自行建立的對象
  • 內建對象(native object):內建在JS語言中的對象,即Array,Math等
  • 宿主對象(host object):有瀏覽器提供的對象

其中,內建對象在入門筆記有講過,JS的數據類型分爲原始類型以及Object對象html

1.1 包裝對象

參考網站:談談JS的包裝對象 還有 淺談JS包裝變量java

1 什麼是包裝對象?

在JavaScript中stringnumberboolean這三者都是基本包裝類型,即他們不是對象(object),但在必定條件下會自動轉化爲對象,所以被稱爲原始類型的「包裝類型」。
舉例子說明,都知道只有對象(object類型)才能擁有屬性以及方法。參考如下代碼:python

var str="seiei";
str.tall="190";
console.log(str.tall);//undefined

該例子中,str是一個字符串,並非對象,當它引用字串符的屬性時(代碼第二行),JS就會將字符串經過隱性調用new String(str)的方式轉換成對象,這個對象繼承了字符串的方法,並被用來處理屬性的引用。一旦屬性引用結束,這個新建立的對象就會銷燬(因此最後調用時undefined)這個過程就叫包裝對象
對於以上方法,能夠直接顯式地建立包裝對象程序員

var str=new String("seiei");
str.tall="190";
console.log(str.tall);//190
typeOf str;//object

2 那麼爲何平時使用字符串就能夠調用諸如indexOf的方法呢?

其實,在咱們調用這些方法和屬性時,JS內部已經隱式地幫咱們幫建立了一個包裝對象了,以上的實際的情形應該是這樣的:ajax

console.log("this a string".indexOf("a"));
console.log(new String("this a string").indexOf("a"));//隱性建立一個字符串對象

引用類型和包裝類型的主要區別是對象的生存期
使用new操做符建立的引用類型的實例,在執行流離開當前做用域以前都一直保存在內存中。
而自動建立的基本包轉類型的對象,則只存在於一行代碼的執行期間,而後當即被銷燬,這也意味着咱們不能在運行時爲基本類型添加屬性和方法。正則表達式

1.2 小總結

沒有使用new時,Number()、Boolean和String()被當作普通函數,把任何類型的數據轉換爲numberbooleanstring類型。算法

還有幾個規則要注意:編程

  • String()來轉換任意類型到string,或者直接調用某個對象的toString()方法,但nullundefined就沒有toString()方法,並且調用number時,語法是這樣的:(num).toString();
  • var b2 = Boolean('false'); 像這樣的轉換布爾值,其值爲true,由於字串符不爲空。
  • 判斷Array要使用Array.isArray(arr);(注意這是一個總體,arr爲參數)
  • 判斷null要使用arg === null;
  • 判斷某個全局變量是否存在用typeof window.arg === 'undefined';
  • 函數內部判斷某個變量是否存在用typeof myVar === 'undefined'
  • 判斷給定屬性是否在當前實例中(不包活繼承而來的)使用obj.hasOwnProperty(propertyname);方法
  • 檢查傳入對象是否爲當前對象的原型,使用obj1.isPrototypeof(obj2)

2 Math對象

JS中除了加減乘除有相對應的符號外,諸如平方開方的算法都得依靠Math對象,Math對象的方法有不少,如下選取一些經常使用的:json

Math.random();//隨機0~1之間的數值
Math.abs(x);//絕對值
Math.ceil(x);//向上取整,如4.1 --> 5, (-5.9) --> (-5)
Math.round(x);//四捨五入,如(-5.52)-->-6
Math.floor(x);//向下取整
Math.max(x,y);//最大
Math.min(x,y);//最小
Math.pow(x,y);//x的y次方
Math.sqrt(x);//開方

3 Date對象

在JavaScript中,Date對象用來表示日期和時間。
獲取系統當前時間,以下:

var now = new date();
now; //2017-07-15T15:04:31.807Z
now.getFullYear(); //2017
now.setFullYear(2017);//設定年份,下面的均可以這樣設置
now.getMonth(); //6,注意!!!月份範圍是0~11,6表示7月!!
now.getDate(); //15
now.getDay(); //6,這是星期
now.getHours(); //23
now.getMinutes(); //11
now.getSeconds(); //23
now.getMilliseconds(); //49,毫秒
now.getTime(); //1500131686539,時間戳

若是想要建立一個指定時間的Date對象
第一種方法是:

var d = new Date(2017,6,15,23,18,30,123);//注意月份

第二種方法是解析字串符:

var d = Date.parse('2015-06-24T19:49:22.875+08:00');//返回時間戳
var d = new Date(1435146562875); //轉化時間戳

顯示本地時間,也能夠顯示調整後的UTC時間

var d = new Date();
d.toLocaleString();//2017-07-15 23:25:05,顯示的字符串與操做系統設定的格式有關
d.toUTCString();//Sat, 15 Jul 2017 15:26:15 GMT,相差8小時

不厭其煩,注意月份取值範圍是0~11


4 RegExp對象(正則表達式)

正則表達式規範都是通用的,因此python那邊也能夠重溫一下。

4.1 字符描述字符

正則表達式字符描述字符:

  • \d:任意數字
  • \w:任意字母或數字 以及 下劃符
  • \s:空格
  • .:任意字符
  • *:零個或多個
  • ?:一個或沒有
  • +:至少一個
  • {n,m}:n到m個
  • (a|b):a或者b
  • []:取值範圍
  • ():用於分組
  • ^:用於行頭
  • $:用於結尾

4.2 建立正則表達式

JavaScript有兩種方式建立一個正則表達式:
第一種是直接經過這樣的形式 /正則表達式/ 寫出來:

var re = /ABC\-001/; //ABC-001

第二種是經過new RegExp('正則表達式')建立一個RegExp對象(這是使用字串符,要注意雙重轉義):

var re = new RegExp("ABC\\-001"); //ABC-001

因爲第二種方法使用的是字符串,因此在定義\符號時,要注意轉義問題

RegExp對象的test()方法用於測試給定的字符串是否符合條件:

re.test("010-12345");//true

4.3 切分字符串

如同python同樣,用正則表達式切分字符串比用固定的字符更靈活

'a b c'.split(/\s+/); // ['a', 'b', 'c']

4.4 分組提取

恰當地使用()分組,正則表達式就可使用提取子串的強大功能。
在RegExp對象上用exec()方法提取出子串來,會返回一個Array第一個元素是正則表達式匹配到的整個字符串,後面的字符串表示匹配成功的子串)。

var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']

4.5 貪婪匹配

採用非貪婪匹配只需在後方加上?符號就能夠了:

var re = /^(\d+?)(0*)$/; //\d+後加上?
re.exec('102300'); // ['102300', '1023', '00']

4.6 全局搜索

JavaScript的正則表達式還有幾個特殊的標誌,最經常使用的是g,表示全局匹配,語法:

/* 兩者等價 */
var re=/[a-zA-Z]+Script/g;
var re =new RegExp("[a-zA-Z]+Script","g");


/* 可屢次執行exec()方法來搜索一個匹配的字符串。當咱們指定g標誌後,每次運行exec(),正則表達式自己會更新lastIndex屬性,表示上次匹配到的最後索引 */

var s = 'JavaScript, VBScript, JScript and ECMAScript';

re.exec(s); // ['JavaScript']
re.lastIndex; // 10,上次匹配到的最後索引

re.exec(s); // ['VBScript']
re.lastIndex; // 20

re.exec(s); // ['JScript']
re.lastIndex; // 29

re.exec(s); // ['ECMAScript']
re.lastIndex; // 44

re.exec(s); // null,直到結束仍沒有匹配到

所以全局搜索不能使用/^...$/限定行頭行尾,那樣只會最多匹配一次。


5 JSON對象

JSON是JavaScript Object Notation的縮寫,它是一種數據交換格式。
JSON其實是JavaScript的一個子集。幾乎全部編程語言都有解析JSON的庫,而在JavaScript中,咱們能夠直接使用JSON,由於JavaScript內置了JSON的解析。

把JavaScript對象變成JSON,就是把這個對象序列化成一個JSON格式的字符串,這樣纔可以經過網絡傳遞給其餘計算機。
若是咱們收到一個JSON格式的字符串,只須要把它反序列化成一個JavaScript對象,就能夠在JavaScript中直接使用這個對象了。

5.1 對象序列化

序列化對象,使用JSON.stringify(),如:

var xiaoming = {
    name:"小明"
}
JSON.stringify(xiaoming);//'{"name":"小明"}'

JSON.stringify()其實能夠接受三個參數,第一個對象,第二個參數用於控制如何篩選對象的鍵值(只是鍵值),第三個用於輸出時按縮進輸出。

第二個參數能夠輸入Array,出指定的屬性
也能夠傳入一個函數,這樣對象的每一個鍵值對都會被函數先處理。

var xiaoming = {
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

JSON.stringify(xiaoming, ['name', 'skills'], ' ');//只輸出name以及skills屬性,還有輸出縮進

function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}

JSON.stringify(xiaoming, convert, ' ');//大寫鍵值,還有輸出縮進

5.2 反序列化

拿到一個JSON格式的字符串,咱們直接用JSON.parse()把它變成一個JavaScript對象,如:

JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}

一樣的JSON.parse()也能夠接受函數(Array無效),用來轉換解析出的屬性

var func = function (key,value) {
    if(typeof(value) === "string") {
        return value.toUpperCase()
    } 
    return value
    };

JSON.parse('{"name":"小明","skill":"python"}',func);//{name:"小明",skill:"PYTHON"}

6 promise對象

Promise 是異步編程的一種解決方案,所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果。從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。
Promise對象表明一個異步操做(test()函數),有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。
當調用已成功函數返回另外一個Promise對象時,會致使自己的狀態無效了,由返回的Promise對象的狀態決定其自己的狀態。

,若是不設置回調函數如(then()catch()),Promise內部拋出的錯誤

下面代碼創造了一個Promise實例:

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(vaule => console.log(value)).catch(err =>console.log(error))

Promise實例構造函數接受一個操做函數,而後這個操做函數分別接受兩個函數,即reject以及resolve函數,能夠用then方法分別指定resolved狀態的回調函數,使用catch指定reject狀態的回調函數。
下面是一個使用Promise對象實現Ajax 操做的例子:

function ajax (method,url,data) {
    var promise = new Promise(function(resolve,reject){
        var request = new XMLHttpResquest();
        request.onreadystatuschange = function(){
            if ( request.readyState === 4 ) {
                if ( request.status ===200 ) {
                    resolve(request.reponseText)
                } else {
                    reject(request.status);
                }
            }
        }
        request.open(method,url);
        request.send(data)
    });
    return promise
}
var p = ajax('GET', '/api/categories');
p.then(function (text) { // 若是AJAX成功,得到響應內容
    log.innerText = text;
}).catch(function (status) { // 若是AJAX失敗,得到響應代碼
    log.innerText = 'ERROR: ' + status;
});
相關文章
相關標籤/搜索