前端知识总结系列笔记一: new Object()和Object.create()的区别

769 阅读4分钟

关于对象包装器

1. 内置对象

JavaScript是面向对象的语言,为了方便操作基本类型值,ECMAScript还提供了3种特殊的引用类型:Boolean, Number, String。
举个栗子,具体看String对象
String对象
String对象是文本值的包装器,除了为变量存储文本,String对象还包含一些属性和方法来获取或操作文本的信息,不需要进行实例化就可以直接使用。例如可以用一个只读的length属性用于返回字符串的长度,运用一些方法如charAt、concat、indexOf、slice等返回开发者所需要的信息(这里不详细介绍这些方法的用途)。
思考1: 字符串‘123’ 和 new String(‘123’)的区别
const a = '123'; // Output: 123 输出值类型 123,是基本数据类型
const b = new String('123'); // Output: String {'123'} 输出对象类型, 是复杂数据类型

Object.getPrototypeOf(a) === Object.getPrototypeOf(b); // true, a和b的原型都是一样的,都指向String内置对象
思考2:字符串什么情况下会转换成String内置对象?
看下面一段代码
const s1 = 'jiaxin';
const s2 = s1.substring(2);
上述这段代码变量 s1 是一个字符串,属于基本类型值。而下面一行代码而是调用了s1的substring()方法,并将放回的结果保存在了s2中。按道理来说,s1是一个基本数据类型而已,不应该有方法,但是确实能调用String内置对象提供的一系列方法,为什么呢?实际上为了实现这种直观的操作,后台已经自动完成了一系列的处理。主要有以下几个过程:
(1)从内存中读取s1这个变量的值
(2)创建String类型的一个实例
(3)在实例上调用指定的方法
(4)销毁这个实例
可以将以上几个步骤想象成执行了下述代码:
const s1 = new String('jiaxin');
const s2 = s1.substring(2);
s1 = null;
总结:
对象包装器就是将原始类型(string、number、boolean...)转换成对应的对象(String、Number、Boolean)。

关于 new Object()

1. 语法

用途: 为给定值创建一个对象的包装器,创建出来的对象是其定值所属内置对象的实例

new Object(a) // a可为数据类型,如 number, string, Object

2. 特征

(1) 与对象的包装类型的创建一致
// 以下创建的两者是一样的
new Object(1);
new Number(1);
控制台的输出

控制台输出

// 再举个栗子, 也是一致的
new Object('111');
new String('111');
控制台输出

注意:如果给定值为null 或 undefined,则返回空对象, 如果给定值是一个对象,则返回原对象,数组同理
new Object(null);
new Object(undefined);
new Object({
    name: 'jiaxin',
    age: 18
});
控制台输出

(2)创建出来的对象为其定值所属内置对象的实例
// instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
new Object('foo') instanceof String; // true
new Object(true) instanceof Boolean; // true
(3)如果Object的参数是一个对象,则返回原对象,数组同理
function Foo () {};
new Object(Foo) === Foo; // true 如果Object的参数是一个对象,则返回原对象

关于 Object.create()

1. 语法

用途:不用定义一个构造函数,该方法凭空创建一个新对象并把新对象内部的[[prototype]]关联到你指定的对象
返回值:一个空对象,带着指定的原型对象和属性

Object.create(proto, [propertiesObject])

参数说明:
(1)proto:新创建对象的原型对象
(2)propertiesObject:可选,不指定则为undefined,是要添加到的新创建对象中的可枚举属性 (即其自身定义的属性,而不是其原型链上的枚举属性)
const Girl = {
    name: 'jiaxin',
    age: 18,
    sayHello: function() {
        console.log(`Hello, I am ${this.name}`);
    }
}

let girl1 = Object.create(Girl); // Output: {}

girl1.__proto__ === Girl; // true 创建出来的对象的原型指向其指定的对象Girl

2. 实现原理

function Foo() {};

const foo = Object.create(Foo);

const fn = function() {};
fn.prototype = Foo;
const foo = new fn()

3. 用new Object()实现Object.create()

function Foo() {};

const fn = Object.create(Foo.prototype);
// 等价于
const fn = new Object();
fn.__proto__ = Foo.prototype;

总结:

1、new Object(a)用于创建一个对象包装器。
(1)如果a为string,number,boolean,则返回其对应的基本包装类型的对象,相当于返回new String(a),new Number(a),new Boolean(a)的实例;
(2)如果a为空,null,undefined,则返回一个空对象{};
(3)如果a为对象或数组,则返回原对象或数组

2、Object.create()用于创建一个新对象并把新对象内部的[[prototype]]关联到你指定的对象