javascript中的对象
一、语法
定义:有两种形式,分别为:文字形式和构造形式。两种方式生成的对象都是一样的,只是文字形式可以同时添加多个属性,而构造形式只能逐个添加。
//文字形式 var obj1 = { id: 1, name: 'Mike' }; //构造形式 var obj2 = new Object(); obj2.id = 1; obj.name = 'Mike'; //结论:二者生成的对象是相同的,文字形式更常见。
二、语言类型
一共有7种,分别是:string 、number 、boolean 、null 、undefined 、object、Symbol(ES6新增)。所以“JavaScript中万物皆是对象”的说法是错误的。不过,object是javascript中最复杂的基本类型了,它包含了很多我们经常使用的对象子类型,例如:String 、Number 、Boolean 、Object 、Function 、Array 、Date 、RegExp 、Error。它们被称为对象子类型。
//对象子类型 console.log([345,45] instanceof Object); //true function fn(){ var a = 235; } console.log(fn instanceof Object); //true
三、内容
对象的内容是由一些存储在特定命名位置的(任意类型的)值组成的,我们称之为属性。需要强调的是,属性值并不会存储在对象容器内部,存储在对象内容区内部的时候属性的名,它们就像指针,指向属性值真正的存储位置。访问属性有两种方式,分别是:“属性访问”和“键访问”。两种方式的区别在于:
(1)“属性访问” 的写法更简洁,所以大多数情况都是使用“属性访问”
(2)“属性访问”对属性名的命名更规范;而“键访问”不但支持使用连接符,还可以计算属性名
var obj = { 'id': 1, 'age-num': 43 }; console.log(obj.id); //1 console.log(obj['id']); //1 console.log(obj.age-num); //报错 : num is not defined console.log(obj['age-num']); //43 console.log(obj['age'+'-num']); //43
四、复制对象的方法
1、浅复制:Object.assign(obj[,obj1,obj2.....])
2、深复制:JSON.parse(JSON.stringify(obj))【前提:obj是JSON安全的,有函数就不安全,JSON没办法进行转化】
//简单的对象:浅复制就够了 var obj = { 'id': 1, 'age-num': 43 }; var copyObj = Object.assign({},obj); copyObj.id = 2; console.log(obj.id); //1 (复制成功) //复杂的对象:深复制 【注:浅复制复制Array、Funtion、Object只复制了引用,不是得到复本】 var obj1 = { 'id': 4545, 'arr': [0,1,2,3,4,5] }; //错误的做法:浅复制 var copyObj1 = Object.assign({},obj1); copyObj1.arr[2] = 100; console.log(copyObj1.arr); //(6) [0, 1, 100, 3, 4, 5] console.log(obj1.arr); //(6) [0, 1, 100, 3, 4, 5] //正确的做法:转化为JSON进行处理【注:前提是obj是JSON安全的,包含函数的是不安全的】 var copyObj2 = JSON.parse(JSON.stringify(obj1)); copyObj2.arr[2] = 'new'; console.log(copyObj2.arr); //(6) [0, 1, "new", 3, 4, 5] console.log(obj1.arr); //(6) [0, 1, 100, 3, 4, 5] //对比 var fnObj = { 'a':'efer', 'fn':function(){ console.log(123); } }; var copyFnObj = JSON.parse(JSON.stringify(fnObj)); console.dir(copyFnObj); //{a:'efer'} 【JSON复制失败】
五、属性描述符
在ES5开始新增了属性描述符。包含有四个特性:value 、writable 、enumerable 、configurable
1、writable : 决定是否可以修改属性的值
var obj = { id: 1 }; Object.defineProperty(obj,'name',{ value: '小新', writable: false, enumerable: true, configurable: true }); obj.id = 2; obj.name = '小白'; //没有修改到,因为writable: false console.log(obj); //{id: 2, name: "小新"}
2、configurable : 只要属性是可以配置的,就可以使用defindProperty()方法来修改属性描述符;(即使writable为false也还是能修改属性的值)属性是不可配置时,不但不能无法修改,而且还不能删除。【例外:即便属性是configurable:false ,我们还是可以把writable的状态由true改为false,但是无法由false改为true】
var obj = {}; Object.defineProperty(obj,'name',{ value: '小新', writable: false, enumerable: true, configurable: true }); Object.defineProperty(obj,'name',{ value: '小白', writable: false, enumerable: true, configurable: false }); console.log(obj); //{name: "小白"} delete obj.name; //删除属性无效 console.log(obj); //{name: "小白"}
3、enumerable : 是否是枚举属性。作用:有些遍历方法只能遍历枚举属性,这样可以避免对特殊属性的遍历。
var obj = {'id':1}; Object.defineProperty(obj,'name',{ value: '小白', writable: true, enumerable: false, //有些遍历方法会忽略不可枚举的属性 configurable: true }); console.log(Object.keys(obj)); //["id"] (忽略不可枚举的属性) for(key in obj){ //(忽略不可枚举的属性) console.log(key); //id } console.log(Reflect.ownKeys(obj)); //(2)["id","name"] (获取对象所有的属性)