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. cf 786 B 线段树优化建图

    cf 786 B 链接 CF 思路 n个点,3种建边方式,规模\(O(n^2)\) 线段树优化建图 注意 读入的数据好坑啊,说好的v,u变成了u,v. 两棵树,一棵出,一棵入.线段树的作用只不过是按照 ...

  2. Android仿QQ复制昵称效果

    本文同步自http://javaexception.com/archives/76 背景: 这几天做一个复制文本的需求,突然看到QQ上复制昵称跟QQ号的效果,觉得很不错,就想要模仿一波,办法比较简单粗 ...

  3. [19/03/18-星期一] 常用类_Math(数学)类&Rondom(随机数)类

    一.Math(数学)类(单独一个Java.Math 包中) java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型.如果需要更加强大的数学运算能力, ...

  4. [19/03/13-星期三] 数组_二维数组&冒泡排序&二分查找

    一.二维数组 多维数组可以看成以数组为元素的数组.可以有二维.三维.甚至更多维数组,但是实际开发中用的非常少.最多到二维数组(我们一般使用容器代替,二维数组用的都很少). [代码示例] import ...

  5. ms17_010利用复现(32位)

    准备阶段: 1,原版windows7:cn_windows_7_enterprise_x86_dvd_x15-70737.iso 2,kali系统,  虚拟机 3,用于32位机的攻击模块:Eterna ...

  6. pooling、relu、convolution的反向传播

    1.pooling的反向传播: https://blog.csdn.net/qq_21190081/article/details/72871704 pooling反向传播的原则:pooling的值和 ...

  7. CentOS 7.1上安装.Net Core

    官方网站给出了几条命令: sudo yum install libunwind libicu curl -sSL -o dotnet.tar.gz https://go.microsoft.com/f ...

  8. jsp的4个作用域区别( pageScope、requestScope、sessionScope、applicationScope)

    简单描述 page里的变量没法从index.jsp传递到test.jsp.只要页面跳转了,它们就不见了. request里的变量可以跨越forward前后的两页.但是只要刷新页面,它们就重新计算了.  ...

  9. Jquery 1.8全选反选删除选中项实现

    JQuery1.6以后,Prop的出现,让1.6以下的全选反选效果全部失效了.以下是修正后的版本: 全选反选效果: $(".checkbox").click(function () ...

  10. Vue nodejs商城项目-商品的分页、排序、筛选

    .分页 ,要查第3页的数据,则跳过2*8条数据,然后返回8条数据. 在实现滚动加载时,页面刚一加载完成并不需要请求所有数据,当用户下拉到页面底部时,再去请求数据并拼接到商品数据列表中. 通过vue-i ...