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是一个字面量对象或实例对象,那么相当于是实现了对象的浅拷贝

js学习日记-new Object和Object.create到底干了啥的更多相关文章

  1. JS学习之--比较两个Object数组是否相等

    一.问题 在js中是不能直接用“==”或者“===”来计算两个数组是否相等的,那么就需要对数组的值进行比较: 二.次解决方案 对于比较两个数组次要的方法有如下几种,为什么说是次要解决方案呢?因为它不能 ...

  2. js学习日记-对象字面量

    一.对象字面量语法 var person={ name:'小王', age:18, _pri:233 } 成员名称的单引号不是必须的 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误 成员名相 ...

  3. js学习日记-隐式转换相关的坑及知识

    隐式转换比较是js中绕不过去的坎,就算有几年经验的工程师也很有可能对这块知识不够熟悉.就算你知道使用===比较从而避免踩坑,但是团队其它成员不一定知道有这样或那样的坑,有后端语言经验的人常常会形成一个 ...

  4. js学习日记 (1)createDocumentFragment() ES6 => 箭头

    只能说是会用和记载,深入理解还需时间. 有关性能优化: 使用createdocumentfragment()方法可以创建某个具有节点该有的所有属性的节点. 使用情况:  提取文档中的某个小部分,修改文 ...

  5. js学习日记-变量的坑

    js变量细节是前端面试经常遇到的问题,可见其重要程度,要想掌握这个知识点,需注意以下几点: 变量提升 所谓变量提升,就是使用了var关键字申明的变量,会提升到所在作用域的顶部.es5的作用域分为全局作 ...

  6. js学习日记-常用正则符号参考

    预定义类 量词 贪婪.惰性.支配性量词 前瞻 边界 RegExp是全局对象,RegExp.$1...$9是全局属性.当执行任意正则表达式匹配操作时,JavaScript会自动更新全局对象RegExp上 ...

  7. js学习日记-各种宽高总结(配图)

    1.窗口和浏览器 window.innerWidth.window.innerHeight   浏览器内部可用宽高 window.outerWidth.window.outerHeight   浏览器 ...

  8. js中的new操作符与Object.create()的作用与区别

    js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...

  9. js原型链接(二)和object类的create方法

    原型链的内部执行方式 <script> function Myclass(){ this.x=" x in Myclass"; } var obj=new Myclas ...

随机推荐

  1. 大整数乘法(POJ2389)

    题目链接:http://poj.org/problem?id=2389 #include <stdio.h> #include <string.h> #define Max 1 ...

  2. Spring Boot 推荐的基础 POM 文件

    名称 说明 spring-boot-starter 核心 POM,包含自动配置支持.日志库和对 YAML 配置文件的支持. spring-boot-starter-amqp 通过 spring-rab ...

  3. ProjectServer任务审批后自动发布

    我们知道ProjectServer汇报工时的顺序是这样: 1.项目成员打开自己的时间表,选择要汇报的任务,在汇报工时栏填写实际工时. 2.汇报工时后点击保存. 3.将汇报工时的任务提交给项目经理. 4 ...

  4. vue开发工具node.js及构建工具webpack

    1.概念 node.js:可以运行JavaScript的服务平台,可以把它当做一个后端程序,只是它的开发语言是JavaScript (通常情况下,JavaScript的运行环境都是浏览器,因此Java ...

  5. 为什么有IP还需要硬件地址,或者说为什么有硬件地址还需要IP

    只用MAC 虽然每个设备都有唯一的硬件地址,但不都是MAC格式. 只用MAC的话理论上是可行的,但是其中 兼容不同的硬件地址,处理起来是非常困难的.而且数据链路层也没有必要处理网络层的逻辑. 只用IP ...

  6. [Linux/Unix]常用命令

    1.查看日志后200行有“TNS字符串的详细信息 file_name |grep TNS 实时查看文件情况: tail -f file_name 2.查看路由情况: #Linux环境 tracerou ...

  7. django-orm简记

    首先orm是什么? orm-------->对象关系映射 专业性解释网上一大推,随便搜搜就能了解大概.在我理解(通俗):一个类 ----- 数据库中一张表 类属性 ----- 数据表中的字段名 ...

  8. java 代码调用函数

    sql 中调用函数 getDistance(lng1 float, lat1 float, lng2 float, lat2 float) 例如: SELECT id, f_seller_id sel ...

  9. 判断Map集合中是否存在某一个key

    方法一: Map<String,String> hashmp = ne HashMap(); hashmp.put("aa", "111"); ha ...

  10. 汉化manjaro下的火狐浏览器

    1.下载 汉化包 sudo pacman -S firefox-i18n-zh-cn 2.查看add-ons下的language选项有没有已安装的包 3.在浏览器的地址栏输入 搜索intl.local ...