小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
创建对象,可以说是编程中最常见的一种操作。 ES5之前,大部分都是通过字面量的形式创建的,还有部分是通过new操作符创建的, ES5引入了Object.create静态方法。
MDN的说明:
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
这里大家需要知道:
- function 有
prototype和__proto__
function a() {};
console.log("prototype:", a.prototype); // prototype: {constructor: ƒ}
console.log("__proto__", a.__proto__); // __proto__ ƒ () { [native code] }
- object 有
__proto__
var a = {};
console.log("prototype:", a.prototype); // prototype: undefined
console.log("__proto__", a.__proto__); // __proto__ {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
今天我们一起来看看这个有趣的Object.create。
继承
既然方法说明中说了是使用一个对象作为原型创建一个新的对象,那么很显然就可以用于继承。
其实现有三个注意点,代码总已标注。
其实继承的方式有很多种,个人觉得这种和类继承,写着比较舒服,也比较简洁实用。
function Animal(name){
this.name = name;
}
Animal.prototype.getName = function(){
return this.name
}
function Person(name,sex){
Animal.call(this,name); // 注意点1:调用父类的构造函数,差不多相当于class的super
this.sex = sex;
}
Person.prototype = Object.create(Animal.prototype); // 注意点2: 原型链设置
Person.prototype.constructor = Person; // 注意点3:修复构造函数,这是容易出错的地方
var person = new Person("小名","男");
console.log("name:" ,person.getName()); // 小名
console.log("constructor:" ,person.constructor); // Person
纯净对象
纯净对象: 没有除了自定义数据外的多余属性。
大家都知道,默认的对象,都有toString, valueOf, hasOwnProperty等等内置属性。
所以,我们很多时候,只需要记录数据,根本不需要这些属性,这个时候 Object.create(null)就闪亮登场。
Reflect.ownKeys(Object.create(null))
我喜欢纯净的东西,你今天喜欢了吗?
这里提出一个问题,如果创建一个纯净对象,并直接带有键值呢?
// 方式一
var pureObject = Object.create(null);
pureObject.name = "小名";
pureObject.age = 12;
// 方式二
var object = {name:"小名", age: 12}
上面两种方式,方式二要高效,你知道为什么嘛?
第二个参数
小结
今天你收获了吗?