内容简介:上一篇文章写了关于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差不多,指向的原型也一致。
但是,如果我们往构造函数里添加属性呢?
function Foo() { this.sayHi = function() { console.log('hello world'); }; } 复制代码
分别打印foo1、foo2
可以看出使用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) 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java Web高级编程
威廉斯 (Nicholas S.Williams) / 王肖锋 / 清华大学出版社 / 2015-6-1 / CNY 99.80
Java成为世界上编程语言之一是有其优势的。熟悉JavaSE的程序员可以轻松地进入到Java EE开发中,构建出安全、可靠和具有扩展性的企业级应用程序。编写《Java Web高级编程——涵盖WebSockets、Spring Framework、JPA Hibernate和 Spring Security》一书的目的正是如此。 《Java Web高级编程:涵盖WebSockets、Sp......一起来看看 《Java Web高级编程》 这本书的介绍吧!