前面的話
javascript中的難點是函數、對象和繼承,前面已經介紹過函數系列。從本系列開始介紹對象部分,本文是該系列的第一篇——初識對象
對象定義
javascript的基本數據類型包括undefined、null、boolean、string、number和object。對象和其他基本類型值不同的是,對象是一種復合值:它將許多值(原始值或者其他對象)聚合在一起,可通過名字訪問這些值
于是,對象也可看做是屬性的無序集合,每個屬性都是一個名值對。屬性名是字符串,因此我們可以把對象看成是從字符串到值的映射
關于復合值和原始值的詳細區別移步至此
對象創建
有以下三種方式來創建對象,包括new構造函數、對象直接量和Object.create()函數
【1】new構造函數
使用new操作符后跟Object構造函數用以初始化一個新創建的對象
var person = new Object(); //如果不給構造函數傳遞參數可以不加括號 var person = new Object; person.name = 'bai'; person.age = 29;
//創建無屬性的空對象 var cody1 = new Object(); var cody2 = new Object(undefined); var cody3 = new Object(null); console.log(typeof cody1,typeof cody2, typeof cody3);//object object object
如果該參數是一個對象,則直接返回這個對象
var o1 = {a: 1}; var o2 = new Object(o1); console.log(o1 === o2);// true var f1 = function(){}; var f2 = new Object(f1); console.log(f1 === f2);// true
如果是一個原始類型的值,則返回該值對應的包裝對象
//String {0: "f", 1: "o", 2: "o", length: 3, [[PrimitiveValue]]: "foo"} console.log(new Object('foo')); //Number {[[PrimitiveValue]]: 1} console.log(new Object(1)); //Boolean {[[PrimitiveValue]]: true} console.log(new Object(true));
若Object()函數不通過new而直接使用,則相當于轉換方法,可以把任意值轉換為對象
[注意]undefined和null會轉換為一個空對象
var uObj = Object(undefined); var nObj = Object(null); console.log(Object.keys(uObj));//[] console.log(Object.keys(nObj));//[]
如果Object()的參數是一個對象,則直接返回原對象
var o = {a:1}; var oObj = Object(o); console.log(Object.keys(oObj));//['a']
利用這一點,可以寫一個判斷變量是否為對象的函數
function isObject(value) { return value === Object(value); } isObject([]) // true isObject(true) // false
【2】對象字面量
javascript提供了叫做字面量的快捷方式,用于創建大多數原生對象值。使用字面量只是隱藏了與使用new操作符相同的基本過程,于是也可以叫做語法糖
對象字面量是由若干名值對組成的映射表,名值對中間用冒號分隔,整個映射表用花括號括起來
不同屬性之間用逗號分隔,屬性名可以是任意字符串,屬性值可以是任意類型表達式,表達式的值是屬性值
//等價于var person = new Object(); var person = {};
var person = { name : 'bai', age : 29, 5 : true };
使用對象字面量的方法來定義對象,屬性名會自動轉換成字符串
//同上 var person = { 'name' : 'bai', 'age' : 29, '5' : true };
[注意]一般地,對象字面量的最后一個屬性后的逗號將忽略,但在IE7-瀏覽器中導致錯誤
//IE7-瀏覽器中報錯 SCRIPT1028: 缺少標識符、字符串或數字 var person = { name : 'bai', age : 29, 5 : true, };
【3】Object.create()
ES5定義了一個名為Object.create()的方法,它創建一個新對象,第一個參數就是這個對象的原型,第二個可選參數用以對對象的屬性進行進一步描述
var o1 = Object.create({x:1,y:1}); //o1繼承了屬性x和y console.log(o1.x);//1
可以通過傳入參數null來創建一個沒有原型的新對象,但通過這種方式創建的對象不會繼承任何東西,甚至不包括基礎方法。比如toString()和valueOf()
var o2 = Object.create(null); // o2不繼承任何屬性和方法 var o1 = {}; console.log(Number(o1));//NaN console.log(Number(o2));//Uncaught TypeError: Cannot convert object to primitive value
如果想創建一個普通的空對象(比如通過{}或new Object()創建的對象),需要傳入Object.prototype
var o3 = Object.create(Object.prototype); // o3和{}和new Object()一樣 var o1 = {}; console.log(Number(o1));//NaN console.log(Number(o3));//NaN
Object.create()方法的第二個參數是屬性描述符
var o1 = Object.create({z:3},{ x:{value:1,writable: false,enumerable:true,configurable:true}, y:{value:2,writable: false,enumerable:true,configurable:true} }); console.log(o1.x,o1.y,o1.z);//1 2 3
對象組成
對象是屬性的無序集合,由鍵名和屬性值組成
【鍵名】
對象的所有鍵名都是字符串,所以加不加引號都可以,如果不是字符串也會自動轉換成字符串
var o = { 'p': 'Hello World' }; var o = { p: 'Hello World' };
var o ={ 1: 'a', 3.2: 'b', 1e2: true, 1e-2: true, .234: true, 0xFF: true, }; //Object {1: "a", 100: true, 255: true, 3.2: "b", 0.01: true, 0.234: true} o;
[注意]如果鍵名不符合標識符命名規則,則必須加上引號,否則會報錯
//Uncaught SyntaxError: Unexpected identifier var o = { 1p: 123 } var o = { '1p': 123 }
【屬性值】
屬性值可以是任何類型的表達式,最終表達式的結果就是屬性值的結果
var o ={ a: 1+2 } console.log(o.a);//3
如果屬性值為函數,則通常把這個屬性稱為“方法”
var o = { p: function (x) { return 2 * x; } }; o.p(1);//2
由于對象的方法就是函數,因此也有name屬性。方法的name屬性返回緊跟在function關鍵字后面的函數名。如果是匿名函數,ES5環境會返回undefined,ES6環境會返回方法名
var obj = { m1: function f() {}, m2: function () {} }; obj.m1.name // "f" obj.m2.name //ES5: undefined obj.m2.name //ES6: "m2"
引用對象
如果不同的變量名指向同一個對象,那么它們都是這個對象的引用,也就是說指向同一個內存地址。修改其中一個變量,會影響到其他所有變量
var o1 = {}; var o2 = o1; o1.a = 1; console.log(o2.a);// 1 o2.b = 2; console.log(o1.b);// 2
如果取消某一個變量對于原對象的引用,不會影響到另一個變量
var o1 = {}; var o2 = o1; o1 = 1; console.log(o2);//{}
實例方法
valueOf()
valueOf()方法返回當前對象
var o = new Object(); o.valueOf() === o // true
toString()
toString()方法返回當前對象對應的字符串形式
var o1 = new Object(); o1.toString() // "[object Object]" var o2 = {a:1}; o2.toString() // "[object Object]"
一般地,使用Object.prototype.toString()來獲取對象的類屬性,進行類型識別,詳細情況移步至此
toLocaleString()
toLocaleString()方法并不做任何本地化自身的操作,它僅調用toString()方法并返回對應值
[注意]Date和Number類對toLocaleString()方法做了本地化定制
var o = {a:1}; o.toLocaleString() // "[object Object]"
參考資料
【1】 W3School-Javascript高級教程——引用類型 http://www.w3school.com.cn/js/pro_js_referencetypes.asp
【2】 阮一峰Javascript標準參考教程——對象 http://javascript.ruanyifeng.com/grammar/object.html
【3】《javascript權威指南(第6版)》第6章 對象
【4】《javascript高級程序設計(第3版)》第5章 引用類型
【5】《javascript語句精粹》第3章 對象
【6】《javascript面向對象精要》 第3章 理解對象
【7】《你不知道的javascript上卷》第3章 對象
文章列表