你不知道的javascript之Object.create 和new区别

原创 2017年06月12日 20:33:31

博客原文地址:http://blog.csdn.net/blueblueskyhua/article/details/73135938

前几天有碰到原型的问题。之前以为自己对原型还是有所了解,但是细细研究,发现自己对原型的理解还是太年轻了。

这里写图片描述

Object.create 和new

创建对象的方式,我以我碰到的两种创建方式,Object.create 和new来说明

var Base = function () {}
var o1 = new Base();
var o2 = Object.create(Base);

那这样到底有什么不一样呢?
这里写图片描述

我先来一段Object.create的实现方式

Object.create =  function (o) {
    var F = function () {};
    F.prototype = o;
    return new F();
};

可以看出来。Object.create是内部定义一个对象,并且让F.prototype对象 赋值为引进的对象/函数 o,并return出一个新的对象。

再看看var o1 = new Base()的时候new做了什么。

JavaScript 实际上执行的是:
var o1 = new Object();
o1.[[Prototype]] = Base.prototype;
Base.call(o1);

new做法是新建一个obj对象o1,并且让o1的__proto__指向了Base.prototype对象。并且使用call 进行强转作用环境。从而实现了实例的创建。

我们来看看两个对象打印情况。
这里写图片描述
看似是一样的。

我们对原来的代码进行改进一下。

var Base = function () {
    this.a = 2
}
var o1 = new Base();
var o2 = Object.create(Base);
console.log(o1.a);
console.log(o2.a);

这里写图片描述

可以看到Object.create 失去了原来对象的属性的访问。
那再看看prototype呢?(一开始没理解prototype和__proto__ 的关系。造成对这两种方式的创建理解非常费解)。
再一次对代码进行改进。

var Base = function () {
    this.a = 2
}
Base.prototype.a = 3;
var o1 = new Base();
var o2 = Object.create(Base);
console.log(o1.a);
console.log(o2.a);

我一开始以为输出的值是2,3。。。以为prototype还是存在的。。结果发现真的发错特错。我们看运行的结果。
这里写图片描述
依旧是如此。

这里写图片描述

那我们就以图说话。

这里写图片描述

这里写图片描述
(F在创建后被销毁)

看完上图,我们就知道了,为什么通过Object.create构造的连Base原型上的属性都访问不到,因为他压根就没有指向他的prototype。这也就说明了__proto__prototype 的区别。所以上面在prototype定义的a,只是Base的prototype对象上的一个属性。

再来看看就是:

  1. new关键字必须是以function定义的。
  2. Object.create 则 function和object都可以进行构建。

instanceof 和 isPrototypeOf

写了创建一个对象实例,并且说了通过原型链来完成这一个个对象之间的联系,但是你怎么知道就一定含有呢?所以我们需要一个判断机制。

这里写图片描述

function Foo(){
    //...
}
Foo.prototype.ff = 2;
var a  = new Foo();
a instanceof Foo; //true

instanceof 说的是在a的整条[[Prototype]] 是否含有Foo.prototype对象。 但是这个方法只能实现对象(a)和函数(带.prototype引用的Foo),如果你想判断两个对象(a 和 b)是否通过[[Prototype]]链关联。只用instanceof就无法实现。

所以这里用到了isPrototypeOf。

var a = {};
var b = Object.ceate(a);

b.isPrototypeOf(a);//在a的[[Prototype]]是否出现过b来判断。

来看看isPrototypeOf实现方式。

function isRelatedTo(o1,o2){
    function F(){}
    F.prototype = o2;
    return o1 instanceof F;
}

上述函数通过了构建一个辅助函数F,构建了一个prototype对象。从而达到instanceof比较的条件。
console.log(a.isPrototypeOf(b) === isRelatedTo(b,a));// true

constructor

我们先来看看下面的代码。

function Foo(){
}
console.log(Foo.prototype.constructor === Foo);//true
var a = new Foo();
console.log(a.constructor === Foo);//true

看起来a.constructor === Foo 为真意味着a的确有一个.constructor指向Foo的.constructor属性,但事实并不是这样的。

function Foo(){
}
Foo.prototype = {}
var a1 = new Foo();
console.log(a1.constructor === Foo);//false
console.log(a1.constructor === Object);//true

可以看到a1并没有.constructor属性。那是为什么呢。?因为a1没有.constructor属性,他会委托[[prototype]]链上的Foo.prototype。但是新建的Foo.prototype也没有.constructor,所以继续往上找,一直到了顶端的Object.prototype。
你可以手动地进行修正.constructor的指向。
所以可以看出.constructor是一个非常不可靠,并且不安全的引用。在开发中尽量避免使用这些引用,。

版权声明:本文为博主原创文章,未经博主允许不得转载。

javascript中Object.create与new的不同

newnew配合构造函数使用,创建一个新对象。//定义class var Person = function (firstName) { this.firstName = firstName; }...
  • bdss58
  • bdss58
  • 2016年04月30日 22:04
  • 1135

JavaScript对象系统深入剖析3-创建对象Object.Create

3.创建对象Object.Create  @吴穹Adam 看这两天同学们的反馈还是觉得比较难懂,因此,决定再举一个例子帮助大家理解吧,后面有关Scope和闭包Closure的精彩内容就只好晚一点写了!...
  • adwu73
  • adwu73
  • 2012年02月01日 07:57
  • 28889

JS中的Object.assign()、Object.create()、Object.defineProperty()

JS中的Object.assign()、Object.create()、Object.defineProperty()
  • DeepLies
  • DeepLies
  • 2016年10月24日 20:25
  • 4082

Object.create方法及其在继承上的应用

方法介绍Object.create 方法是JavaScript中用于创建对象的一个方法 。 Object.create接收两个参数,第一个表示要继承的对象,第二个参数表示也是一个对象,用于对新创建的...
  • TuoHai_
  • TuoHai_
  • 2017年06月09日 10:10
  • 272

javascript:利用Object.create()方法创建对象

在javascript里面,我们知道有两种常见的创建对象的方法,一种是使用对象直接量: 对象直接量是由若干值/键对组成的映射表,值/键对用逗号”,“分隔开,整个部分用花括号”{}“括起来。 例如:...
  • hutaoer06051
  • hutaoer06051
  • 2012年09月15日 22:38
  • 5197

JS 对象复制Object.assign和Object.create

Object.create简介 创建一个拥有指定原型和若干指定属性的对象。多用于对象继承。 语法 Object.create(prototype,[proptertiesObject])参数 ...
  • qq_20678155
  • qq_20678155
  • 2017年03月31日 16:24
  • 911

JS原型链 new 与 Object.Create()区别 代码及继承的方法

/*var F=function(){} var son=new F(); console.log(son.__proto__==F.prototype)//true*/ /* var F={a:...
  • fangchao3652
  • fangchao3652
  • 2016年01月21日 16:18
  • 4428

JavaScript中的new操作符和Object.create()

在JS中使用new操作符及构造函数创建对象和使用Object.create()方法创建对象的区别...
  • hrgzhy
  • hrgzhy
  • 2016年04月06日 00:09
  • 3311

Object.create

Object.create(parent): 三件事: 1. 创建一个对象                 2. 继承指定父对象                 3. 为新对象扩展新属性   ...
  • java_zhaoyanli
  • java_zhaoyanli
  • 2016年03月15日 00:16
  • 3201

Object.create 与 new function 区别

首先来看看两种语法各是如何创建对象的 Object.create() var test = {val: 1}; var testA = Object.create(test); testA.val...
  • u010119868
  • u010119868
  • 2014年02月12日 18:13
  • 2168
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:你不知道的javascript之Object.create 和new区别
举报原因:
原因补充:

(最多只允许输入30个字)