Object.create()
Object.create(proto, [propertiesObject]) 创建一个新对象,使用现有的对象来提供新创建的对象的proto。
- proto : 必须。表示新建对象的原型对象,即该参数会被赋值到目标对象(即新对象,或说是最后返回的对象)的原型上。该参数可以是null, 对象, 函数的prototype属性 (创建空的对象时需传null , 否则会抛出TypeError异常)。
- propertiesObject : 可选。 添加到新创建对象的可枚举属性(即其自身的属性,而不是原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。
- 返回值:在指定原型对象上添加新属性后的对象。
1)创建对象的方式不同
- new Object() 通过构造函数来创建对象, 添加的属性是在自身实例下。
- Obj ect.create() es6创建对象的另一种方式,可以理解为继承一个对象, 添加的属性是在原型下。使用现有的对象来提供新创建的对象的__proto__
var a = { rep : 'apple' }
// new Object() 方式创建
var b = new Object(a)
console.log(b) // {rep: "apple"} 属性在实例下
console.log(b.__proto__) // {}
console.log(b.rep) // {rep: "apple"}
// Object.create() 方式创建
var c = Object.create(a)
console.log(c) // {} 属性是在原型下
console.log(c.__proto__) // {rep: "apple"}
console.log(c.rep) // {rep: "apple"}
2)创建对象属性的性质不同
创建一个以另一个空对象为原型,且拥有一个属性p的对象
省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o = Object.create({}, { p: { value: 42 } })
o.p = 24
o.p//42
o.q = 12 //后添加属性
for (var prop in o) {
console.log(prop)//"q"
}
delete o.p//false
Object.setPrototypeOf
Object.setPrototypeOf(object, prototype) 该方法的作用与 proto 相同,用来设置一个对象的 prototype 对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
var proto = {
y: 20,
z: 40
};
var o = { x: 10 };
Object.setPrototypeOf(o, proto);
Object.defineProperty
Object.defineProperty(obj, prop, desc) 直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
-
obj 需要定义属性的当前对象
-
prop 当前需要定义的属性名
-
desc 属性描述符
value writable 描述赋值方式能否修改属性 configrable 描述属性定义是否配置,以及可否删除 enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中
- 数据描述符 --特有的两个属性(value,writable)
let Person = {}
Object.defineProperty(Person, 'name', {
value: 'jack',
writable: true // 默认false,不可改变
})
描述符中的某些属性被省略,会使用以下默认规则
2. 存取描述符 --是由一对 getter、setter 函数功能来描述的属性
get:一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined。
set:一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined。
let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
get: function () {
return temp
},
set: function (val) {
temp = val
}
})
属性的特性以及内部属性
javacript 有三种类型的属性
- 命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
- 命名访问器属性:通过getter和setter进行读取和赋值的属性
- 内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性[[Prototype]],你不能直接访问这个属性,但可以通过Object.getPrototypeOf()方法间接的读取到它的值。虽然内部属性通常用一个双吕括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性