深刻了解JavaScript對象(2)--函數、對象

1.[[Call]]屬性是函數獨有的,代表該對象能夠被執行。因爲僅函數擁有該對象,ECMAScript定義typeof操做符對任何具備[[Call]]屬性的對象返回「function」。正則表達式

注:某些瀏覽器曾經在正則表達式中包含[[Call]]屬性,致使後者被錯誤鑑別爲函數。如今,全部的瀏覽器行爲都一致,typeof不會再將正則表達式鑑別爲函數。瀏覽器

2.函數具備兩種字面形式。第一種爲函數聲明,第二種爲函數表達式。這兩種區別在於函數聲明會提早,意味着能夠先使用函數後聲明。app

// 函數聲明
function add(num1, num2){
    return num1 + num2;
}

// 函數表達式
var add = function(num1, num2){
    return num1 + num2;
};

3.array.sort()方法,默認將全部值轉成字符串,再進行比較。函數

var array = [1, 2, 7, 4, 10];
array.sort(function(a, b){
    return a - b;
});
console.log(array);    // [1, 2, 4, 7, 10]
array.sort();
console.log(array);    // [ 1, 10, 2, 4, 7 ]

4.call、apply和bindthis

注:call調用方式,func.call(this. arg1, arg2),apply調用方式,func.apply(this, [arg1, arg2]),bind返回一個函數。code

var name = '李四';
var person = {
    name: '張三',
    sayName: function(){
        console.log(this.name);
    }
};
person.sayName();    // 張三
person.sayName.apply(window);    // 李四
person.sayName.call(window);    // 李四
var aaa = person.sayName;
aaa();    // 李四
var aaa = person.sayName.bind(person);
aaa();    // 張三

五、屬性探測
因爲屬性能夠在任什麼時候候添加,因此有時候就有必要檢查對象是否已有一個屬性。如下模式探測是錯誤的。問題在於if判斷中的值是一個對象、非空字符串、非零數字或true時,判斷爲真;而當值是一個null、undefined、0、false、NaN或空字符串時爲假。因爲一個對象屬性能夠包含這些假值,因此下面代碼有可能會出現問題。更加可靠的判斷屬性是否存在應該是使用in操做符。in操做符在給定對象中查找一個給定名稱的屬性,若是找到則返回true。對象

if(peroson.age){
    // do something
}

在大多數時候,in操做符是最好的選擇。可是當須要檢查屬性是自有屬性仍是原型屬性時,則須要使用hasOwnProperty()方法。該方法在給定的屬性存在且爲自有屬性時返回true。
六、屬性枚舉ip

  • 全部可枚舉的屬性均可以經過for-in循環遍歷。可枚舉屬性的內部特徵[[Enumerable]]都被設置爲true。字符串

  • Object.keys()方法,能夠某一對象的全部可枚舉屬性。get

for-in循環返回的和Object.keys()返回的可枚舉屬性有一個區別。for-in循環同時也會遍歷原型屬性,Object.keys()只返回自有(實例)屬性。

  • 可使用propertyIsEnumerable()方法檢查一個屬性是否爲可枚舉的。

var person = {
    name: '張三'
};
person.propertyIsEnumerable('name')    // true

七、屬性特徵

  • 經過Object.defineProperty()方法來改變屬性特徵。Object.defineProperty()方法接受3個參數:擁有該屬性的對象、屬性名和包含須要設置的特徵的屬性描述對象。屬性描述對象具備和內部特徵同名的屬性,但名字中不能包含中括號。因此能夠用enumerable屬性來設置[[Enumerable]]特徵。

當使用Object.defineProperty()方法設置屬性不可配置後,沒法再次經過此方法設置爲可配置。

  • 經過Object.defineProperties()方法能夠同時定義多個屬性。該方法接收兩個參數:須要改變的對象和一個包含全部屬性信息的對象。

var person = {};
Object.defineProperties(person, {
    _name: {
        value: '張三',
        enumberable: true,
        configurable: true,
        writable: true
    },
    name: {
        get: function(){},
        set: function(){}
    }
})
  • 經過Object.getOwnPropertyDescriptor()方法能夠獲取屬性特徵。該方法接收兩個參數:對象和屬性名。若是屬性存在,則返回一個屬性描述對象。

  • Object.preventExtensions()建立一個不可擴展的對象。該方法接收一個參數,就是對象。經過Object.isExtensible()來檢查[[Extensible]]的值。

  • Object.seal()封印對象。封印的對象是不可擴展的且全部屬性都不可配置。經過Object.isSealed()判斷對象是否被封印。

  • Object.freeze()凍結對象。凍結的對象是一個數據屬性都爲只讀的被封印對象,被凍結對象沒法解凍。經過Object.isFrozen()判斷對象是否被凍結。

相關文章
相關標籤/搜索