javascript Object.create()究竟发生了什么
这是我在博客园的第一篇博客,早上看了一个大牛的博客,关于javascript继承的,对于大牛使用Object.create()实现继承的方式觉得点问题,就自己研究了一下,所以就有了这篇帖子。
本帖只讲Object.create()。因为我也才做一年前端,理解不对的,希望大牛们帮忙指正。
在博客开始前先谈下我多 prototype和__proto__的粗浅的认识。
1、prototype 只有类才有这个属性,一般通过函数声明 function xx(){} 和函数表达式 var xx=function(){} 定义的对象都有这个属性,而通过new生成的函数对象则没有这个属性。类的prototype属性指向类的原型对象
2、__proto__ 这个指向父类的prototype属性所指向的对象,即父类的原型对象; 函数声明和函数表达式定义的类的__proto__指向Object的原型对象function Empet(){}.比如 function A(){} ; var a= new A(); a.__proto__和A.prototype指向的是同一个对象。
3、通过new 创建的对象是没有 prototype属性的
先上一张图片,这样大家了解的比较清楚。图应该大家都看得懂,这里就不解释了。

基于以上粗浅的认识开始下面的探讨。
先创建类A
function A(){
this.x="i am x"
}
var a =new A();
console.log("A.prototype : "+A.prototype+" ,A.__proto__ : "+A.__proto__);//A.prototype : [object Object] ,A.__proto__ : function Empet(){}验证第一点
console.log("a : "+a.prototype+" ,a.__proto__ : "+a.__proto__); //a : undefined ,a.__proto__ : [object Object] 验证第3点
验证验证 第二点a.__Proto__ 就是 A.prototype
a.__proto__.getName=function(){
console.log("create by a.__proto__");
}
var a2 =new A();
a2.getName(); //create by a.__proto__
验证成功,通过new创建的对象的__proto__跟类的prototype指向同一个对象,即类的原型对象
现在开始正题——Object.create 发生了什么
var obj =Object.create(A);
《javascript权威指南》6.1节中说 Object.create()创建一个新对象,其中第一个参数是对象的原型。
如果按照这种说法 obj.prototype 应该指向A;所以obj.prototype跟A拥有相同的方法和属性,现在为A定义一个show方法 看obj.prototype是否能调用这个show()方法
A.show=function(){
return "i am A"
}
console.log("A.show(): "+A.show()); //A.show(): i am A
A能调用show方法,验证obj.prototype 是否能调用show()方法
console.log("obj.prototype: "+obj.prototype.show());//报错 undefined is not a function
oh,mygod,难道我心中的圣经《javascript权威指南》上写的是错的吗?我宁可相信是我理解错了,或是翻译错了。
经过断点调试发现,obj拥有__proto__属性而没有prototype属性。我前面也说过,在我粗浅的认识中, 只有通过new创建的对象才有这样的性质——有__proto__属性而没有prototype属性。所以我断定obj是通过new创建的对象。断点调试发现 obj的_proto__是指向A的。
查阅了一下资料 微软的官方文档上是这样写的
"Object.create()返回值为一个具有指定的内部原型且包含指定的属性(如果有)的新对象" 注意这里 "指定的内部原型" 指定的内部原型是__proto__ 而不是prototype。咦,难道真的是这样吗?
如果是这样的话就是说 obj是new出来的对象, 在Object.create() 过程中 产生了一个类 这个类是obj的父类。父类new出了obj这个实例对象。 父类的prototype是指向A的, 所以obj的__proto__就指向了A。
为了验证这个想法,程序走起。
console.log("obj.__proto__.show(): "+obj.__proto__.show()); //obj.__proto__.show(): i am A
console.log("obj.x : "+obj.x); //undefined oh soga。这个是正常的,因为A中定义x是this.x="i am x" x是A实例的属性,obj报undefined是正常的
obj的__proto__能够调用show()方法,说明obj的__proto__确实指向A
关于第二个验证obj.x是多余的。obj 本身没有x属性,沿着原型链 obj的prototype Object.create()创建的父类也没有定义x。obj的prototype的prototype也就是A,A函数里面有x,但是A本身没有定义x所以报undefined是正常的。果然基础不够扎实,才写了这多余的验证。
再随便看下原型链继承。
A.x="gg";
console.log("obj.x A have defined x : "+obj.x); //obj.x A have defined x : gg
果然跟想的一样,obj没有x,它就需找它的父类(obj_father),父类没有定义this.x,注意这里是this.x 而不是父类.x(obj_father.x)。在父类中只有this.x才能被子类调用。父类.x是父类自己的私有属性。父类没有x所以找到父类的prototype即A。A有.x 所以就输入A的x。没有A没有就报undefined;
就刚刚突发奇想 想看一下new一个实例对象会产生什么后果。
var b= new obj();//object is not a function
看到这个,我不得不嘲笑自己,本来就该这样,都不肯思考,还要写个程序验证!!!基础啊基础

有理解不对的,希望大牛指正,不胜感激。
javascript Object.create()究竟发生了什么的更多相关文章
- js学习日记-new Object和Object.create到底干了啥
function Car () { this.color = "red"; } Car.prototype.sayHi=function(){ console.log('你好') ...
- Object.create 函数 (JavaScript)
创建一个具有指定原型且可选择性地包含指定属性的对象. 语法 Object.create(prototype, descriptors) 参数 prototype 必需. 要用作原型的对象. 可以为 ...
- javascript一种新的对象创建方式-Object.create()
1.Object.create() 是什么? Object.create(proto [, propertiesObject ]) 是E5中提出的一种新的对象创建方式,第一个参数是要继承的原型,如果不 ...
- [设计模式] JavaScript 之 原型模式 : Object.create 与 prototype
原型模式说明 说明:使用原型实例来 拷贝 创建新的可定制的对象:新建的对象,不需要知道原对象创建的具体过程: 过程:Prototype => new ProtoExam => clone ...
- Object.create() __https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
Object.create() 方法会使用指定的原型对象及其属性去创建一个新的对象. 语法 Object.create(proto[, propertiesObject]) 参数 proto 新创建对 ...
- Object.create() vs new SomeFunction() in javascript
Object.create builds an object that inherits directly from the one passed as its first argument. Wit ...
- [Javascript] Prototype 2 Object.create()
function Fencepost (x, y, postNum){ this.x = x; this.y = y; this.postNum = postNum; this.connections ...
- javascript的创建对象object.create()和属性检测hasOwnPrototype()和propertyIsEnumerable()
Object.create("参数1[,参数2]")是E5中提出的一种新的对象的创建方式. 第一个参数是要继承到新对象原型上的对象; 第二个参数是对象属性.这个参数可选,默认为fa ...
- js中的new操作符与Object.create()的作用与区别
js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...
随机推荐
- OpenSource.SerializationLibrary
1. Cap'n Proto protocol buffer的主要作者之一创建的新项目.其主页描述Cap'n Proto的性能比PB快很多. http://kentonv.github.io/capn ...
- codeforces round#509
博主水平不高, 只能打完$4$题, QAQ什么时候才能变强啊嘤嘤嘤 订正完6题了, 还想打今天下午的CF , 只能迟十分钟了, 掉分预定 A. Heist 输出 $max - min + n - 1 ...
- C#程序如何以管理员身份运行
VISTA 和 Windows 7 都使用了UAC来控制程序访问,对于一些需要使用管理员身份运行的程序就得右键以管理员身份运行. C# 编程中可以使程序自动使用管理员身份运行,也就是我们常常看到一些程 ...
- 厉害了,PS大神真的能改变世界!
今天要介绍的这位PS大神 名叫 Katrina Yu 她的操作真的神了 不管多普通的场景 她都能帮你改头换面 在后院破旧的椅子上喝着咖啡 一转眼就骑着魔法扫帚 飞上了天,与月亮肩并肩 看原图还以为是在 ...
- [Python] 代码中有中文注释会报错
原因 如果文件里有非ASCII字符,需要在第一行或第二行指定编码声明. 解决方法 在第一行或是第二行加入这么一句# -- coding: utf-8 -- ASCII知识普及: ASCII(Ameri ...
- powershell上传证书
https://www.cnblogs.com/threestone/p/4001632.html powershell上传证书
- Partition Array into Disjoint Intervals LT915
Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...
- Docker 介绍和使用
Docker 技术可以实现容器装载软件和依赖库,类似于封闭的Linux系统,默认相当于有root权限,可以快速移植和部署到其他机器上. Docker 容器技术可以理解为:仓库(储物间),镜像(类似于面 ...
- 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)
传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...
- 2019.01.02 bzoj3513: [MUTC2013]idiots(fft)
传送门 fftfftfft经典题. 题意简述:给定nnn个长度分别为aia_iai的木棒,问随机选择3个木棒能够拼成三角形的概率. 思路:考虑对于木棒构造出生成函数然后可以fftfftfft出两个木 ...