前端知识总结系列笔记二: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)
复制代码

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

查看所有标签

猜你喜欢:

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

Learning jQuery

Learning jQuery

Jonathan Chaffer、Karl Swedberg / Packt Publishing / 2007-7-7 / GBP 24.99

jQuery is a powerful JavaScript library that can enhance your websites regardless of your background. In this book, creators of the popular jQuery learning resource, learningquery.com, share the......一起来看看 《Learning jQuery》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具