× 目錄 [1]定義 [2]創建 [3]組成[4]引用 前面的話 javascript中的難點是函數、對象和繼承,前面已經介紹過函數系列。從本系列開始介紹對象部分,本文是該系列的第一篇——初識對象 對象定義 javascript的基本數據類型包括undefined、null、boolean、stri ...
×
目錄
[1]定義 [2]創建 [3]組成[4]引用前面的話
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));
【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,emumerable:true,configurable:true}, y:{value:2,writable: false,emumerable: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);//{}
參考資料
【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章 對象