携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 19 天,点击查看活动详情
start
- 最近有一个方法经常出现在我眼前:
Object.create()
; - 今天就去学习一下这个方法;
MDN
Object.create()
方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。
1. 语法
Object.create(proto)
Object.create(proto, propertiesObject)
2. 参数
-
proto
新创建对象的原型对象。
-
propertiesObject
可选如果该参数被指定且不为
undefined
,则该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应于Object.defineProperties()
的第二个参数。
3. 返回值
一个新对象,带着指定的原型对象及其属性。
基本使用与注意事项
- 第一个参数必须传递。
Object.create()
// TypeError: Object prototype may only be an Object or null: undefined
- 第二个属性尝试:
/* 传入数字不报错,但是不生效 */
var obj = Object.create({}, 1)
console.log(obj) // {}
/* 传入布尔值不报错,但是不生效 */
var obj = Object.create({}, false)
console.log(obj) // {}
/* 传入字符串报错 */
var obj = Object.create({}, 'str')
console.log(obj) // Uncaught TypeError: Property description must be an object: s // 属性描述必须是一个对象:s
/* 传入对象 */
var obj = Object.create({}, {})
console.log(obj) // {}
var obj = Object.create({}, { name: '123' })
console.log(obj) // TypeError: Property description must be an object: 123
var obj = Object.create({}, { name: { value: '123' } })
console.log(obj) // {name: '123'}
// 完整的用法
var obj = Object.create(
{},
{
name: {
value: '名称', // 包含这个属性的数据值
configurable: true, // 表示能否通过 delete 删除属性,默认为 false;
enumerable: true, // 是否可遍历,默认为 false;
writable: true // 是否可修改,默认为 false;
},
age: {
value: '123', // 包含这个属性的数据值
configurable: true,
enumerable: true,
writable: true
}
}
)
console.log(obj) // { name: '名称', age: '123' }
- 原型
正常的原型继承:
var person = {
name: '人',
age: 18,
say() {
console.log('你好')
}
}
var obj = Object.create(person, {
name: {
value: '名称'
},
like: {
value: 'study'
}
})
console.log(obj) // {name: '名称', like: 'study'}
console.log(obj.name) // 名称
console.log(obj.age) // 18
obj.say() // 你好
console.log(obj.__proto__ === person) // true
null
var obj = Object.create(null)
console.log(obj.__proto__) // undefined
{}
var obj = Object.create({})
console.log(obj.__proto__) // {}
其他创建对象的方式
常见的创建对象的方式有两种:
- 字面量
- new的形式
var obj1 = { name: 11 }
var obj2 = new Object({ name: 22 })
var obj3 = Object.create({ name: 333 })
console.log(obj1, obj2, obj3)
/*
{name: 11}
{name: 22}
{}
*/
console.log(obj1.__proto__ === Object.prototype, obj2.__proto__ === Object.prototype, obj3.__proto__)
/*
true
true
{name: 333}
*/
个人小节:
- 字面量的形式创建的对象, 原型指向
Object.prototype
; - new的形式创建的对象,原型指向 new的那个构造函数;
- 而
Object.create
创建的对象,原型指向传入的第一个参数;
其他
看到有人说道 Object.create(null) 和 Object.create({})的区别
,先去谷歌浏览器打印一下。
var obj = Object.create(null)
console.log(obj)
var obj = Object.create({})
obj.__proto__.__proto__.__proto__===null
结论:相对来说。以 null 为原型生成的对象,更纯粹,以至于没有从 Object.prototype
继承任何对象方法。而第一个参数为{}
的情况,可以沿着原型链寻找直到寻找到 null , 所以它可以在原型链上获得Object.prototype
上的属性和方法。
end
- 加油啦