对象的定义语法
声明形式
var myObj={
key:value,
...
}
构造形式
var myObj=new Object();
myObj.key=value;
JS的六种主要类型
- string
- number
- boolean
- null
- undefined
- object
内置对象(对象子类型)
- String
- Number
- Boolean
- Object
- Function
- Array
- Date
- RegExp
- Error
内容
var myObj={
a:2
};
myObj.a;//2——属性访问
myObj["a"];//2——键访问
可计算属性名
可以在文字形式中使用[ ]包裹一个表达式来当作属性名。
属性与方法
从技术角度来说,函数永远不会“属于”一个对象,所以把对象内部引用的函数称为“方法”是不妥的。
数组
数组期待的是数值下标。最好只用对象来存储键/值对,只用数组来存储数值下标/值对。
如果试图向数组添加一个属性,但是属性名“看起来”像一个数组,那么它会变成一个数值下标(因此会修改数组的内容而不是添加一个属性)。
复制对象——浅复制
var newObj=Object.assign( {},myObject );
Object.assign方法的第一个参数是目标对象,之后还可以跟一个或多个源对象。它会遍历一个或多个源对象的所有可枚举的自有键,并把它们复制(使用=操作符赋值)到目标对象,最后返回目标对象。
属性描述符
var myObj={
a:2
};
Object.getOwnPropertyDescriptor(myObj,"a");
/*{
value:2,
writable:true,
enumerable:true,
configurable:true
}*/
普通的对象属性对应的属性描述符除了key:value,还包含另外三个特性:writable(可写)、enumerable(可枚举)、configurable(可配置,将其修改为false是单向操作,无法撤消)。
可以使用Object.defineProperty(...)
来添加一个新属性或者修改一个已有属性(如果它是configurable)并对特性进行设置。
不变性
- 对象常量:结合writable:false和configurable:false就可以创建一个真正的常量属性。
- 禁止拓展:
Object.preventExtensions(...)
。 - 密封:
Object.seal(...)
会创建一个密封的对象,实际上是在一个现有对象上调用Object.preventExtensions(...)
并把所有现有属性标记为configurable:false。所以密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性(虽然可以修改属性的值)。 - 冻结:
Object.freeze(...)
会创建一个冻结对象,实际上是在现有对象调用Object.seal(...)
并设置为writable:false,这样就无法修改它们的值。这是应用在对象上的级别最高的不可变性。
[[GET]]
对象默认的内置[[GET]]操作首先在对象中查找是否有名称相同的属性,如果找到就会返回这个属性的值。如果无论如何都没有找到名称相同的属性,那[[GET]]操作会返回值undefined。需要注意的是,这种方法和访问变量时是不一样的。如果你引用了一个当前词法作用域中不存在的变量,并不会像对象属性一样返回undefined,而是会派出一个ReferenceError异常。
[[PUT]]
Getter和Setter
通常来说getter和setter是成对出现的。
存在性
var myObj={
a:2
};
("a" in myObj);//true
("b" in myObj);//false
myObj.hasOwnProperty("a");//true
myObj.hasOwnProperty("b");//false
in操作符会检查属性是否在对象及其[[Prototype]]原型链中。hasOwnProperty(...)只会检查属性是否在myObj中,不会检查[[Prototype]]。
*:in实际上检查的是某个属性名是否存在。对于数组来说这个区别非常重要,4 in [2,4,6]的结果并不是你的期待的true,因为[2,4,6]这个数组中包含的属性名是0、1、2,没有4。
- 枚举
propertyIsEnumerable(...)//会检查给定的属性名是否直接存在于对象中
Object.keys(...)//会返回一个数组,包含所有可枚举属性
Object.getOwnpropertyNames(...)//会返回一个数组,包含所有属性,无论是否可枚举
遍历
forEach(...)//会遍历数组中的所有值并忽略回调函数的返回值
every(...)//会一直运行直到回调函数返回false
some(...)//会一直运行直到回调函数返回true
for...of
var myArray=[1,2,3];
for(var v of myArray){
console.log(v);
}
//1
//2
//3
自定义迭代器
var myObj={
a:2,
b:3
};
Object.defineProperty(myObj,Symbol.iterator,{
enumerable:false,
writable:flse,
configurable:true,
value:function(){
var o=this;
var idx=0;
var ks=Object.keys(o);
return{
next:function(){
return{
value:o[ks[idx++]],
done:(idx>ks.length)
};
}
};
}
});
//手动遍历myObj
var it=myObj[Sysbol.iterator]();
it.next();//{value :2,done:false}
it.next();//{value :3,done:false}
it.next();//{value :undefined,done:true}
//用for...of遍历myObj
for (var v of myObj){
console.log(v);
;
//2
//3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。