面试题:创建对象的几种方式

156 阅读2分钟

一、前言

平时我们写代码的时候必定会使用到对象,通常我们是用最直接的字面量方式创建

var obj = {}

但是其实还有两种方式可以实现创建对象:

  • new Object()

  • Object.create()

二、对象字面量

对象字面值是封闭在花括号对({})中的一个对象的零个或多个"属性名-值"对的(元素)列表

let obj1 = {
    name: 'a'
}
obj1.age = 23
obj1.sayName = function() {
    console.log(`My name is ${this.name} !`);
}

obj1.sayName(); //My name is a !
obj1 instanceof Object // true
obj1.__proto__ === Object.prototype // true

三、new Object()

可以看到这里是通过new关键字创建一个实例对象

下面给出new简单实现流程:

// 下面简单实现new过程
function _new(obj1, ...arg) {
  // 1. 创建一个新的对象  
  let obj2 = {}; // 创建一个空对象
  // 2. 将新对象执行原型操作,指向构造函数的原型  
  Object.setPrototypeOf(obj2, obj1.prototype); 
  // 3.  将 this 绑定到新对象上
  let res = obj1.call(obj2, ...arg);  
  // 4. 在构造函数有返回值的情况进行判断
  return res instanceof Object ? res  obj2; 
}

下面可以看看看看new Object()

首先它可以接收一个参数value,然后根据参数value的数据类型,返回对应类型的对象:

  • 如果value为基本数据类型StringNumberBoolean,则返回对应类型的对象
  • 如果value本身为对象,则返回其本身
  • 如果省略了value参数,或valuenullundefined,则返回自身无任何属性的Object对象,即返回一个空对象
let objA = {  rep : 'apple' }
let objB = new Object(objA)
console.log(objB) // {rep: "apple"}
console.log(objA.__proto__ === Object.prototype); // true
console.log(objB.rep) // apple

这样一比较,其实字面量创建和new关键字创建并没有区别,字面量创建更高效更简洁

四、Object.create()

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__,简单来说就是使用现有对象作为新对象的原型

其接收两个参数:

  • proto:新创建对象的原型对象

  • propertiesObject:可选,要添加到新对象上的可枚举的属性

下面来举个例子

const person = {
    isHuman: false,
    func: function () {
        console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
    }
};

const me = Object.create(person, {
    p: {  // 添加到me
        value: 42,
        writable: true, // 是否可以修改属性的值
        enumerable: true, // 属性是否可以枚举
        configurable: true // 是否可以配置该属性,比如删除操作
    }
});
me.name = 'Matthew';
me.isHuman = true;
console.log(me.__proto__ === person) // true
me.func();  // My name is Matthew. Am I human? true

如果传入null,即 Object.create(null),表示 它没有原型,也就是说将null设置成了新创建对象的原型,这样新对象就不会有原型链上的属性了

五、区别

  • 字面量和new关键字创建的对象是Object的实例,原型指向Object.prototype,继承内置对象Object

  • Object.create(arg, pro)创建的对象的原型取决于argargnull,新对象是空对象,没有原型,不继承任何对象;arg为指定对象,新对象的原型指向指定对象,继承指定对象

六、结束语

如果觉得这篇文章对你有帮助,可以伸出你的小手,为这篇文章点个赞

我是前端路上一位新晋的萌新,怀着学习的态度,怀着认识各位同伴的心态,把自己的知识分享出来,除了让自己对知识认知更加巩固,也希望大家能够通过我写的文章学到一点微薄的知识,如果知识内容有误,可以在评论区或者下面公众号告诉我,我会立刻更改

最后,我也创建了一个 【前端收割机】的公众号,希望大家可以关注一波,里面的文章都是掉头发之作