js对象
对象和原型
对象
若干属性的集合就是对象,一切引用类型都是对象,都是属性的集合
let arr = [1,2]
arr.name = 'kimi';
console.log(arr.length) // 2
console.log(arr.name) // 'kimi'
属性描述符
let obj = {
a: 2
};
Object.getOwnPropertyDescriptor(obj, 'a');
// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }
<1> [[writable]]
表示是否能修改属性的值,默认值是true
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
writable: false, // 不可写
configurable: true,
enumerable: true,
})
obj.a = 3; // 严格模式下会报错,非严格模式下会忽略
obj.a // 2
<2> [[configurable]] 默认值true
是否可以通过defineProperty来配置对象
let obj = {};
Object.defineProperty(obj, 'a', {
value: 2,
writable: true,
configurable: false, // 不可配置
enumerable: true,
})
obj.a = 3; // 仍然可以修改属性值
obj.a // 3
Object.defineProperty(obj, 'a', {
value: 2,
writable: true,
configurable: true, // 不管什么模式都会报错
enumerable: true,
})
如果使用Object.defineProperty创建新属性但是不填写配置,writable、configurable、enumerable默认都是false。
let obj = {};
Object.defineProperty(obj, 'a', {})
Object.getOwnPropertyDescriptor(obj, 'a');
// {
// value: undefined,
// writable: false,
// enumerable: false,
// configurable: false
// }
如果设置了configurable是false。仍然可以将writable的值从true设置为false,但是不可以从false设置为true。
如果设置了configurable是false,不可以使用delete删除属性
<3> [[value]] 默认值undefined
包含这个属性的数据值
<4> [[enumerable]] 默认值true
是否可以for in、object.keys、 JSON.stringify递归出来
访问描述符
[[get]] [[set]]
let obj = {};
Object.defineProperty(obj, 'a', {
get: function() {
return this._a;
},
set: function(val) {
this._a = val;
}
})
let obj = {
get a() {
return this._a;
},
set a(val) {
this._a = val
}
}
以上两种都会在对象中创建一个不包含值的属性,自动调用get、set函数。如果设置了set、get则会忽略value和enumerable配置
不变性
<1> 设置writable、configurable为false
设置writable、configurable为false就可以创建一个真正的常量属性,不可修改、重定义、删除
<2> Object.preventExtensions() 不可扩展
let obj = {
a: 2
};
Object.preventExtensions(obj) ; // 不可以添加新属性,并且保留已有属性
obj.b = 3 ;
obj.b // undefined
<3> Object.seal() 密封
会在现有对象身上调用Object.preventExtensions,并把所有属性标记为configurable为false
不能添加新属性,也不能重新配置或者删除现有属性。
可以
修改现有的值
<4> Object.freeze() 冻结
会在现有对象身上调用Object.seal,并且把所有属性标记为writable为false
不能添加新属性,也不能重新配置或者删除现有属性。
不可以
修改现有的值
存在性
let obj = {
a: undefined
}
obj.a // undefined
obj.b // undefined
都是undefined,如何来区分哪个为obj的属性呢?
hasOwnProperty()
hasOwnProperty只会判断自身是否有属性。in 操作符会检查属性是否存在原型中。
2 in [1,2] // false 判断的是key 数组的key是下标 0,1
new操作符
- 创建一个空的简单JavaScript对象(即{});
- 链接该对象(即设置该对象的构造函数)到另一个对象;
- 将步骤1新创建的对象作为this的上下文 ;
- 如果该函数没有返回对象,则返回this。
function _new(fun) {
return function() {
// 创建一个空的简单JavaScript对象
let obj = {};
// 链接该对象(即设置该对象的构造函数)到另一个对象
obj.__proto__: fun.prototype;
// 将步骤1新创建的对象作为this的上下文
let returnObj = fun.apply(obj, arguments)
// 如果该函数没有返回对象,则返回this
if(typeof returnObj === 'object'){
return returnObj
}else{
return obj
}
}
}
Object.create()
Object.create()方法创建一个新对象,并使用现有的对象来提供新创建的对象的proto
Object.create = function (o) {
var F = function () {};
F.prototype = o;
var newObj=new F();
return newObj;
};
使用{}和Object.create(null)创建对象的区别。
Object.create(null)创建的对象proto为null。没有继承的方法例如toString()是一个完全空的对象。而{}继承于Object