第三章 对象
3.对象
3.1 语法
对象定义方式:
1. 声明
var obj = {
key: value;
}
2. 构造形式
var obj = new Object();
obj.key = value;
3.2 类型
1. 基本类型
string number boolean null undefined object
PS: null 有时会被当成一个对象
// 这是语言本身的一个bug
typeof null // object
js中有许多特殊的对象子类型,称之为复杂基本类型。
内置对象
也属于对象子类型
String Number Boolean Object Function Array Date RegExp Error
var str1 = 'str1';
typeof str1; // 'string'
str1 instanceof String; // false
var str2 = new String('str2');
typeof str2; // 'object'
str2 instanceof String; // true
Object.prototype.toString.call(str2); // [object string]
'str1'是一个原始值,只是一个字面量,不可变。
在必要时,语言会把字符串转换成一个String对象
null 和 undefined 没有对应的构造形式,只有文字形式。相反,Date 只有构造
3.3 内容(即属性)
存储在对象容器内部的是这些属性的名称(永远是字符串),由指针指向真正的存储位置
.a 属性访问
['a'] 键访问
3.3.1 可计算的属性名
myObject[prefix + name];
var prefix = 'foo';
var obj = {
[prefix + 'bar']:'hello';
}
obj['foobar'];
常用场景:ES6 的Symbol (新的数据类型),包含一个不透明且无法预测的值
3.3.2 属性与方法
本质来说并没有把函数变成一个“方法”。因为this是在运行时根据调用位置动态绑定的
“函数” 和 “方法” 在js中可互换
3.3.3 数组
数组也支持 [] 访问形式
可以给数组添加属性,但 length 值不会发生改变
3.3.4 复制对象
一种巧妙的复制方法(JSON安全的对象):
var newObj = JSON.parse(JSON.stringfy(someObj));
ES6 Object.assign(..);实现浅复制
参数 1:目标对象
2: 一个或多个源对象
它会遍历一个或多个源对象的可枚举的自有键,并复制到目标对象(使用=赋值操作)
所以 writable 类似的属性不会被复制
3.3.5 属性描述符
value writable enumerable configurable
可用Object.defineProperty(..)设置
用Object.getOwnPropertyDescriptor(..)获取
// get
var obj ={
- a:2;
- }
- Object.getOwnpropertyDescriptor(obj,'a');
- // {
- // value: 2,
- // writable:true,
- // enumerable:true,
- // configurable:true
- // }
- // set
- var obj = {};
- Object.defineProperty(obj,'a',{
- value:2;
- writale; false;
- configurable: false;
- });
- obj.a; // 2
- obj.a = 3; // TypeError
- delete obj.a; // 失败
- obj.a; //2
改写不可写属性抛出 TypeError 异常
即便是configurable:false 1.可将 writale 由 true 改为 false
2.禁止删除原有属性
3.3.6 不变性
1. 对象常量
结合 writable:false 和 configurable:false 就可创建常量
2. 禁止扩展
Object.preventExtensions(..);
3. 密封
obj.seal();
在 2 的基础上并将现有属性标记为configurable:false
不能添加新属性,不能重新配置或删除任何现有属性
4. 冻结
obj.freeze(..);
在 3 的基础上并将所用属性标记为 writable:false
3.3.7 [[Get]]
上文代码: obj.a 实现了 [[Get]] 获取操作
obj.b; // undefined
3.3.8 [[Put]]
给对象赋值时实现了 [[Put]] 操作
3.3.9 Getter 和 Setter
均为 隐藏属性
成对出现
3.3.10 存在性
1. in //检查属性是否在对象及其 [[prototype]]原型链 中
2. hasOwnProperty(..); // 不会检查原型链
------比较强硬的方法: Object.prototype.hasOwnProperty.call(obj,'a');
3. 枚举
obj.propertyIsEnumerable('a'); // true
Object.keys(obj); // ['a',...] // 包含所有可枚举属性
Object.getOwnPropertyNames(obj); //['a',....] //包含所有属性,可枚举和不可枚举
.constructor 共有且不可枚举,但是可以被修改。
3.4 遍历
1. for .. in
遍历对象的可枚举属性
2. forEach(..)
遍历数组中所有的值
3. every(..)
一直运行到回调函数返回false
4.some(..)
一直运行到回调函数返回true
5. for .. of
遍历数组
首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象(内置或自定义的@@iterator)next()方法来遍历所有返回值