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

栏目: 编程语言 · 发布时间: 6年前

内容简介:上一篇文章写了关于Object.create()的实现原理,而在实际应用中,我们通常会把一个构造函数的原型作为参数来创建一个对象。传送门,Object.create()的相关介绍以及实现原理new Foo()和Object.create()同是创建对象的不同方式,接下来我们来讨论一下,new Foo()和Object.create(Foo.prototype)的区别。

上一篇文章写了关于Object.create()的实现原理,而在实际应用中,我们通常会把一个构造函数的原型作为参数来创建一个对象。

传送门,Object.create()的相关介绍以及实现原理 juejin.im/post/5d15c5…

new Foo()和Object.create()同是创建对象的不同方式,接下来我们来讨论一下,new Foo()和Object.create(Foo.prototype)的区别。

new Foo()

1、 构造函数创建对象

用于自定义对象类型的属性和方法,可通过new操作符,返回对象的多个实例。
复制代码
function Foo(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        console.log(`My name is ${this.name}`);
    }
}

const foo1 = new Foo('jiaxin', 18, 'Coder');
const foo2 = new Foo('xiaohua', 36, 'Doctor');

// foo1,foo2分别保存着Foo的一个不同的实例,这两个对象都有一个constructor属性,指向Foo
foo1.constructor === Foo; // true
foo2.constructor === Foo; // true

// foo1,foo2既是Foo的实例,同时也是Object的实例
foo1 instanceof Foo; // true
foo1 instanceof Object; // true
foo2 instanceof Foo; // true
foo2 instanceof Object; // true
复制代码

接下来我们来思考一下new Foo()的实现

const fn = function() {};
fn.prototype = Foo.prototype;
const foo = new fn();
Foo.call(foo, 'jiaxin', 16, 'coder'); // 在foo中调用Foo函数,调用后foo就拥有了Foo的所有属性和方法
复制代码

Object.create(Foo.prototype)

1、 原型式继承创建对象

看下面一段代码

function createObject(o) {
    function F() {};
    F.prototype = o;
    return new F();
}
复制代码

上述createObject()函数内部,先创建了一个临时性的构造函数,然后将传入的对象o作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。Object.create()实际上是对这种原型式继承的规范,在传入一个参数的情况下,Object.create()方法则与createObject()方法的行为相同。 现在我们要用原型式继承的方式创建一个跟new Foo()一样的实例

function Foo() {
}

const foo1 = new Foo();
const foo2 = Object.create(Foo.prototype);
foo1.__proto__ === foo2.__proto__; // true
console.log('foo1', foo1);
console.log('foo2', foo2);
复制代码

看看打印结果,好像foo1和foo2差不多,指向的原型也一致。

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

但是,如果我们往构造函数里添加属性呢?

function Foo() {
    this.sayHi = function() {
        console.log('hello world');
    };
}
复制代码

分别打印foo1、foo2

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

可以看出使用new 操作符创造的Foo的实例foo1将构造函数的作用域赋给这个新对象foo1,因此foo1有了sayHi这个方法,而用Object.create(Foo.prototype)这个方法不具有构造函数Foo的属性和方法。

如果我想让Object.create(Foo.prototype)创建出来的对象也具有Foo的实例和方法呢? so Easy!

// 方法1:把Foo的属性和方法添加到全局,在给foo2的同名方法赋值
const foo2 = Object.create(Foo.prototype);
Foo(); // 添加到window;
foo2.sayHi = window.sayHi;

// 方法2:利用Object.create()方法的第二个参数
const foo2 = Object.create(Foo.prototype, {
    sayHi: {
        writable: true,
        value: function() {
            console.log('hello world!'),
        }
    }
})

// 方法3:使用call()(或者apply())
Foo.call(foo2)
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

第三次浪潮

第三次浪潮

[美]阿尔文·托夫勒 / 黄明坚 / 中信出版集团 / 2018-7 / 79.00元

《第三次浪潮》是美国著名未来学家阿尔文•托夫勒的代表作之一。1980年出版之际,随即引起全球热评,堪称中国改革开放的指南。本书阐述了由科学技术发展引起的社会各方面的变化与趋势。托夫勒认为,人类迄今为止已经经历了两次浪潮文明的洗礼:第一次是农业革命,人类就此从原始渔猎时代进入以农业为基础的文明社会,并历经千年,直到工业革命的到来。随后,人类社会历时300年摧毁了落后的第一次浪潮文明,并在“二战”后1......一起来看看 《第三次浪潮》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换