Object.create()
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
Object.create()
方法可以定义自己的原型
语法:
语法: Object.create(proto,[propertiesObject])参数:
参数1: 新创建对象的原型对象.
参数2: 对象形式的配置项.具体参考Object.defineProperties()的第二个参数.
返回值:
返回一个新对象,带着指定的原型对象和属性.
注意: 如果proto的值不是null或者对象,会报错.
TypeError: Object prototype may only be an Object or null: undefined"
const person = {
isHuman: false,
printIntroduction: function() {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
};
const me = Object.create(person);
me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten
me.printIntroduction();
// "My name is Matthew. Am I human? true"
var obj1 = Object.create(null)
console.log(obj1); // 没有任何属性
obj1.num = 1;
var obj2 = Object.create(obj1) //利用create实现继承
console.log(obj2); // 里边有num:1
console.log(obj2.num); // 1
var obj = Object.create(null)
// obj.toString() //没有这个方法
console.log(obj);
// 面试题: 不是所有的对象都继承Object.prototype.
// var obj = Object.create(null)这种情况就不继承
看一道题:
const person = {
address: {
country:"china",
city:"hangzhou"
},
say: function () {
console.log(`it's ${this.name}, from ${this.address.country}`)
},
setCountry:function (country) {
this.address.country=country
}
}
const p1 = Object.create(person)
const p2 = Object.create(person)
p1.name = "Matthew"
p1.setCountry("American")
p2.name = "Bob"
p2.setCountry("England")
p1.say()
p2.say()
答案
it's Matthew, from England
it's Bob, from England
解析
Object.create方法会创建一个对象,并且将该对象的__proto__属性指向传入的对象,所以p1和p2两个对象的原型对象指向了同一个对象,接着给p1添加了一个name属性,然后调用了p1的setCountry方法,p1本身是没有这个方法的,所以会沿着原型链进行查找,在它的原型上,也就是person对象上找到了这个方法,执行这个方法会给address对象的country属性设置传入的值,p1本身也是没有address属性的,
但是和name属性不一样,address属性在原型对象上找到了,并且因为是个引用值,所以会成功修改它的country属性,接着对p2的操作也是一样,然后因为原型中存在引用值会在所有实例中共享,所以p1和p2它们引用的address也是同一个对象,一个实例修改了,会反映到所有实例上,所以p2的修改会覆盖p1的修改,最终country的值为England。