有趣的Object.create

236 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

创建对象,可以说是编程中最常见的一种操作。 ES5之前,大部分都是通过字面量的形式创建的,还有部分是通过new操作符创建的, ES5引入了Object.create静态方法。

MDN的说明:

Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

这里大家需要知道:

  1. function 有 prototype__proto__
function a() {};
console.log("prototype:", a.prototype);  // prototype: {constructor: ƒ}
console.log("__proto__", a.__proto__);   // __proto__ ƒ () { [native code] }
  1. 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等等内置属性。

截图_20211226091243.png

所以,我们很多时候,只需要记录数据,根本不需要这些属性,这个时候 Object.create(null)就闪亮登场。

Reflect.ownKeys(Object.create(null))

截图_20211426091424.png

我喜欢纯净的东西,你今天喜欢了吗?

这里提出一个问题,如果创建一个纯净对象,并直接带有键值呢?

// 方式一
var pureObject = Object.create(null);
pureObject.name = "小名";
pureObject.age = 12;

// 方式二
var object = {name:"小名", age: 12}

上面两种方式,方式二要高效,你知道为什么嘛?

第二个参数

小结

今天你收获了吗?