function Car () {this.color = "red";
}
Car.prototype.sayHi=function(){console.log('你好')
}var car =new Car();
var car2 =  Object.create(Car);

new XXX()时发生了什么?

var obj={};
obj.__proto=Car.prototype
Car.call(obj)

第一步,创建了一个空对象obj
第二步,将空对象的__proto__成员指向了Car函数的原型属性,该原型属性是一个原型对象,也就意味着obj的原型属性上拥有了Car.prototype中的属性或方法

第三步,将Car函数中的this指针指向obj,obj有了Car构造函数中的属性或方法 ,然后Car函数无返回值或返回的不是对象,直接返回obj,否则返回Car函数中的对象


tip:__proto__是什么

每个对象都有一个[[prototype]}属性,这个属性是隐藏属性,谁创建了它,该属性就指向谁的prototype属性,因为是隐藏属性,不能直接访问,所以有的浏览器提供了一个__proto__属性来访问,然而这不是一个标准的访问方法,所以ES5中用Object.getPrototypeOf函数获得一个对象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一个对象的[[prototype]]

Object.create时发生了什么?

Object.create()方法创建一个新对象,并使用现有的对象来提供新创建的对象的__proto__,关键代码如下

关键代码如下:

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

可以看到Object.create内部创建了一个新对象newObj,默认情况下newObj.__proto__== F.prototype,在本例中则重写了构造函数F的原型属性,最终的原型关系链为newObj.__proto__== F.prototype == o

如果现有的对象是一个构造函数,即var car2=Object.create(Car)会发生什么呢?

console.log(car2.color)    //undefined
console.log(car2.sayHi())  //undefined

执行代码发现都是undefined, 为什么会这样呢?

问题1:因为Object.create内部的新对象是new F()创建的,跟Car构造函数没有半毛钱的关系,所以自然不能访问到Car中的属性了

问题2:调用car2.sayHi()时首先判断car2对象有没有相应的方法,如果没有,则查找car2的原型链上有没有该方法,car2的原型属性是Car构造函数(可以通过car2.__proto__来证明),构造函数没有sayHi方法,自然也就是undefined了。

那如果将var car2=Object.create(car)又发生了什么呢?

function Car () {this.color = "red";this.person={name:'张三'}
}
Car.prototype.sayHi=function(){console.log('你好')
}
var car =new Car();
var car2 =  Object.create(car);
car2.person.name ='李四'
console.log(`car是${car.person.name},car2是${car2.person.name}`)

相当于实现了原型继承方式(注意不是原型链继承),本质上来说是对一个对象进行了浅拷贝


最终结论:

1. Object.create(o),如果o是一个构造函数,则采用这种方法来创建对像没有意义

2.Object.create(o),如果o是一个字面量对象或实例对象,那么相当于是实现了对象的浅拷贝

转载于:https://www.cnblogs.com/94pm/p/9113434.html

js学习日记-new Object和Object.create到底干了啥相关推荐

  1. Node.js学习日记3

    1.__filename 解析:__filename表示当前正在执行的脚本的文件名.它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同.如果在模块中,返回的值是模块文件的路径. 2 ...

  2. JS学习日记--面向对象

    一.js面向对象 1.什么是面向对象 面向对象编程(OOP)是一种计算机编程架构,他将真实世界的各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟 2.面向对象的目的 ...

  3. JS学习日记(二)字符与对象

    一.字符串 一.定义 JS中字符串与C类似,用单引号或双引号表示字符串,在单/双内部引用单/双要加反斜杠\ 'Did she say \'Hello\'?' // "Did she say ...

  4. js学习日记-Bingo Card

    用循环进行重复操作 例做一个Bingo Card html部分 ... <table> <tr> <td id="s0"> </td> ...

  5. 我的 Vue.js 学习日记 (七) - 事件与修饰符

    上节回顾 上节写了一个v-for与table的简单互动,脑子里回忆一下,嗯 ~ 还是回去再看一遍吧... 本节目标 今天看一下事件与修饰符,并且把有疑惑的地方敲一遍,亲眼看一下输出结果.由于时间有限, ...

  6. Vue.js学习日记03

    Vue.js样式绑定 Vue.js class class 与 style 是 HTML 元素的属性,用于设置元素的样式 class 属性绑定 为 v-bind:class 设置一个对象,从而动态的切 ...

  7. JS学习日记--正则基础语法

    一.正则表达式 正则表达式是由普通字符及特殊字符组成的对字符串进行过滤的逻辑公式 创建方式 字符量的方式: var reg = /abc/: 构造函数 var reg = new RegExp(&qu ...

  8. JS学习笔记(九)深拷贝浅拷贝【Array、Object为例】

    JS学习笔记(九) 本系列更多文章,可以查看专栏 JS学习笔记 文章目录 JS学习笔记(九) 一.赋值&复制 二.浅拷贝(shallow copy) 1. 什么是浅拷贝 2. 数组的浅拷贝 ( ...

  9. 《JS学习》Object对象

    介绍 JavaScript中的对象其实就是一组数据和功能的集合. 通过new操作符后跟要创建的对象类型的名称来创建. ​ new: ​ 从指定模具中复刻出一个一模一样的空间,此空间与外界隔离,视为实例 ...

最新文章

  1. Java每天5道面试题,跟我走,offer有!(八)
  2. goldengate的实施过程
  3. oracle之trunc(sysdate)
  4. Flask开发成语接龙游戏,闲来无事手机玩玩自己写的游戏吧!
  5. bzoj1951 [Sdoi2010]古代猪文 lucas+CRT+exgcd
  6. Java并发编程之ReentrantLock重入锁
  7. 算法大赛十强战队解题方案大公开!【附PPT下载】
  8. eclipse注释中插入当前时间
  9. Mysql 如何做双机热备和负载均衡 (方法一)
  10. python的sorted函数和operator.itemgetter函数
  11. 26.【案例:敏感词汇过滤】
  12. 阿里巴巴代码规范考试
  13. C# 实现eval,支持任意个数、任意基本类型的参数
  14. android-第一行代码-第六章数据储存——持久化技术 含MMKV和Room新知识点(温故而知新)学习记录
  15. CocoaPods Trunk 发布
  16. OpenStack部署之Placement项目(7-4)
  17. 事务 Transcation 是什么?
  18. Word中的插入页眉 ?Word中页眉横线如何删除?
  19. 微型计算机使用的crt信号,《微型计算机及其接口技术》课程学习方法篇(2)...
  20. 冒泡排序法(C语言)

热门文章

  1. Linux下多节点SSH无密码互联实现
  2. 如何用chrome查看post get及返回的数据
  3. MySQL 5.7.18 zip 文件安装过程
  4. IBM Bluemix体验:Containers持久存储
  5. 欣赏一下OFFICE 2013 PLUS吧
  6. SQL:waitfor的使用
  7. 生活随笔:态度需要端正
  8. 1 理解Linux系统的“平均负载”
  9. 特征图注意力_向往的GAT(图注意力模型)
  10. P1019 单词接龙 (DFS)