constructor、prototype、isPrototypeOf、instanceof、in 、hasOwnProperty
constructor、prototype、isPrototypeOf、instanceof、in 、hasOwnProperty等等
constructor:对象构造器。存在于原型对象中?,相当于php中的基类中的构造方法?可以获取构造函数本身
prototype:访问对象构造器的原型,只有函数才具有这个属性。
isPrototypeOf:如果对象 A 存在于 对象obj的原形链中,则 A.prototype.isPrototypeOf(obj)返回true,而obj必定继承了A 的属性。
判断实例化的对象box是否指向了原型对象,基本上只要实例化了,实例化的对象会自动指向构造函数()
__proto__:访问对象的原型链在当前对象的上一级对象,即对象的父级对象,非W3C 或 ECMAscript 标准,是浏览器对原型继承的一种实现手段,存在于firefox 和 chrome ,IE下不存在这个属性。
在对象的继承关系中,对象obj的构造器 constructor 其实是存在于原型链中的,
即 obj.constructor 实际上是 obj.__proto__.constructor, obj.hasOwnProperty('constructor'); 为 false
function Y() {this.y=99;}
var obj = new Y();
console.log(obj.constructor); //Y
console.log(obj.hasOwnProperty('constructor')); //false
console.log(obj.__proto__.hasOwnProperty('constructor')); //true
//=====
function X(){this.x=88; }
function Y() {this.y=99;}
Y.prototype = new X();
var obj = new Y();
console.log(obj.constructor); //X
console.log(obj.hasOwnProperty('constructor'));//false
console.log(obj.__proto__.hasOwnProperty('constructor')); //false
console.log(obj.__proto__.__proto__.hasOwnProperty('constructor')); //true
访问对象时,对于 obj.__proto__.x=value 则必定有 obj.x=value,
obj.constructor.prototype 上的属性将被保存在obj.__proto__中。
function Y() {this.y=99;}
Y.prototype = {a:11};
var obj = new Y();
obj.__proto__.hasOwnProperty("a");//true
Y.prototype.a=77;
console.log([obj.a,obj.__proto__.a,obj.y,obj.__proto__.y]);
/*77,77,99,obj.__proto__.y 是 undefined,y 属性是由对象构造器直接产生的而不是从原形链继承来的*/
new 运算构造obj对象之后,obj访问继承来的属性时,是通过__proto__ 访问的,而不是通过obj.constructor.prototype 访问,
因此,如果修改obj.constructor.prototype指向另一个对象,并不会影响obj继承原有的属性。
Y.prototype = {b:22};
console.log(obj.b); //undefined
console.log(obj.a); //77
in: 如果对象 obj 有属性 property(包括继承来的和不可列举属性,不同于 for in 循环中的 in,for in 忽略了不可列举属 性), 则'property' in obj 返回 true,这个运算不存在于初期版本的javascript。
propertyIsEnumerable: 如果对象obj上的属性property可以被列举出来(可被 for in 循环遍历), 则 obj.propertyIsEnumerable('property') 返回true,值得注意的 是,propertyIsEnumerable对继承来的属性一律判断为false,这一般被认为是ECMA Script 规范的一个设计上的错误。
hasOwnProperty:如果对象obj 上的属性 property 不是继承的来的,则 obj.hasOwnProperty('property') 返回true。
delete: 删除对象自身上的属性,不能删除继承来的属性,不能通过 delete window.x 来删除使用 var 声明的全局变量 x,也不能函数函数声 明,在的 firefox 和 ie9 的调是其中执行的代码,却能的删除全局变量,这在网页脚本中是不会发生的事,当delete 语句删除属性成功时 返回 true,否则返回 false。
var f = function(){};
f.prototype = { x:99 };
var o = new f;
console.log(o.hasOwnProperty('x')); //false
console.log(o.x); //99
delete o.x ;
console.log(o.x); //99
var x = 1;
window.hasOwnProperty('x'); //true
delete window.x;
console.log(x); // error,x is not defined ,fire bug, it will not happen in webpage's script codes.
window.xx = 789; //这样定义的属性是可以删除的
console.log(xx); //789
delete window.xx; //true
console.log(xx); //undeifned ,
instanceof: 如果obj对象是构造函数Fun的一个实例,则 obj instanceof Fun 返回 true,值得注意的是,instanceof 并不检 查 Fun 函数,而是检查 Fun.prototype,是基于"原形链"的,因此,即使 obj instanceof Fun 返 回 true,obj 也可能不具有 Fun 构造器中定义的属性,因为 Fun 不一定是 obj 的构造器。
function A(){ this.a = 'a';}
function Bar(){ this.b= 'b';}
function C(){ this.c = 'c';}
var na = new A();
Bar.prototype = na;
var bar = new Bar();
console.log(bar instanceof Bar); //true
Bar.prototype = new A();
console.log(bar instanceof Bar); //false ,instanceof 检测 函数的 prototype, 后一个 new A 不等于前一个 new A,(不相同的对象不会相等)
C.prototype = na;
console.log(bar instanceof C); //true
console.log(na.isPrototypeOf(bar)); //true
console.log(bar.hasOwnPrototype('c')); //false
关于instanceof,试考察下面代码:
function P(){this.p=11;};
var pro = new P();
function X() {this.x=88;}
function Y() {this.y=99;}
Y.prototype =pro;
var obj = new Y();
1、对象构造器在哪
console.log(obj.hasOwnProperty('constructor')); //false
console.log(obj.constructor); //P
console.log(obj.__proto__.constructor);//P
console.log(obj.__proto__.constructor === Y.prototype.constructor); //true
这说明执行new时,obj.constructor 即 obj.__proto__.constructor 实际是 Y.prototype.constructor 而不是 Y.
2、对象构造器修复
但是,有一点小问题,考察一下 y 属性:
console.log(obj.y); // 99
console.log(obj.__proto__.y); //undefined
y 属性既然不是来自于“原型链”,那自然是来自于对象构造器,但是 P 函数中并没有定义 y 属性,
从“类式继承” 形成的“继承链” 看来,P 只是“继承链”的源头,也就是最顶级的 “基类”, obj 对象实例的的构造来源于“子类” y 函数,
这是 js 对象继承系统中 “模拟类式继承” new 与“原型继承” prototype 之间的一点裂缝,
很多人执着于修复这个裂缝,于是有了构造器修复的做法.
默认状态下声明一个函数fun,有fun.prototype.constructor===fun,于是:
obj.constructor = Y ; //修复构造器,赋一个constructor属性来覆盖掉继承链上的constructor
console.log(obj.hasOwnProperty('constructor')); //true
console.log(obj.constructor); //Y
console.log(obj.__proto__.constructor); //P
3、obj instancof Fun 为 true 并不意味着 Fun 一定是 obj 对象的构造器,Fun 可能并不存在于 obj 的继承链中:
X.prototype = pro;
console.log(obj instanceof X); //true
console.log(obj.x);//undefined , X 不是 obj 的构造器
console.log(obj instanceof Y); //true
console.log(obj.y);//99
上面的代码中P函数如果改为
function K(){ this.k=66; }
function P(){this.p=11;};
P.prototype = new K();
那么未修复构造器前,继承链上的构造函数将是K而不是P,也会有:
console.log(obj instanceof X); //true
console.log(obj.x);//undefined
console.log(obj instanceof Y); //true
console.log(obj.y);//99
console.log(obj instanceof K); //true
console.log(obj.k); //66
4、Object.create()
新版本的 ECMAScript 为 Object 对象扩展了一些方法,
Object.create(pro)可以基于 pro 为原型创建一个对象,其效果相当于
var f = function(){};
f.prototype = pro;
var obj = new f();
try:
function P(){this.p=11;}
function K(){this.k=22;}
function F(){this.f=33;}
var pro = new K();
P.prototype = pro;
var o= new P();
var obj = Object.create(o);
console.log(o,obj); // 都是 {p:11,k:22}
console.log(obj.constructor); // K
console.log(obj.__proto__.constructor); //k
console.log(obj instanceof P); //true
console.log(obj instanceof K); //true
console.log(obj instanceof F); //false
F.prototype = pro;
console.log(obj instanceof F); //true
5、Object 与 Function:
console.log(Function instanceof Object); //true
console.log(Object instanceof Function); //true
先有 Function 还是先有 Object ?下面这个现象或许能解释,Object 才是“最顶级”的对象
console.log(Object.__proto__.__proto__===Function.prototype) ; // false
console.log(Function.__proto__.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null ,Object 的对象原型已经是女娲级的了
constructor、prototype、isPrototypeOf、instanceof、in 、hasOwnProperty的更多相关文章
- 面向对象的程序设计(二)理解各种方法和属性typeof、instanceof、constructor、prototype、__proto__、isPrototypeOf、hasOwnProperty
//理解各种方法和属性typeof.instanceof.constructor.prototype.__proto__.isPrototypeOf.hasOwnProperty. //1.typeo ...
- javascript 中isPrototypeOf 、hasOwnProperty、constructor、prototype等用法
hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员. isPrototypeOf是用来判断要检查 ...
- JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性
在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...
- Javascript中的__proto__、prototype、constructor
今天重温了下Javacript,给大家带来一篇Javascript博文,相信对于Javacript有一定了解的人都听过prototype原型这个概念,今天我们深度的分析下prototype与__pro ...
- 大白话通俗易懂的讲解javascript原型与原型链(__proto__、prototype、constructor的区别)
javascript原型和原型链是js中的重点也是难点,理论上来说应该是属于面向对象编程的基础知识,那么我们今天为什么要来讲这个呢?(因为我也忘了,最近看资料才揭开面纱…… 哈哈哈) 好了,直接进入 ...
- JavaScript——this、constructor、prototype
this this表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window: 如果在函数中使用this,则this指代什么是根据运行时此函数在什么对象上被调用. 我们还可以使用a ...
- 关于JS call apply 对象、对象实例、prototype、Constructor、__proto__
关于call与apply的理解容易让人凌乱,这里有个方法可供参考 tiger.call(fox,arg1,arg2...) tiger.apply(fox,[arg1,arg2...]) 理解为 fo ...
- 第197天:js---caller、callee、constructor和prototype用法
一.caller---返回函数调用者 //返回函数调用者 //caller的应用场景 主要用于察看函数本身被哪个函数调用 function fn() { //判断某函数是否被调用 if (fn.cal ...
- <JavaScript>constructor、prototype、__proto__和原型链
在看了网上很多相关的文章,很多都是懵逼看完,并不是说各位前辈们写得不好,而是说实在不容易在一两次阅读中理解透.我在阅读了一些文章后,自己整理总结和绘制了一些相关的图,个人认为会更容易接受和理解,所以分 ...
随机推荐
- kettle 通过JDBC 连接SQL Server(Error occurred while trying to connect to the database)
在连接数据(MS SQLServer 2008)发现:Error occurred while trying to connect to the database 然后找资料看,都不是问题所在,最后一 ...
- OC + RAC (四) combineLatest和merg
-(void)_test4{ ///RAC combineLatest和merge // combineLatest只有当两个信号都发送了 订阅者才能收到信息 结果一次收到 结果是数组 // merg ...
- 方法返回前面有if - else if - else ,最终返回值是?
-(NSString *)testA{ int a = ?; ) { return @"a大于5"; } ) { return @"a不大于5"; } retu ...
- [USACO17DEC]Barn Painting (树形$dp$)
题目链接 Solution 比较简单的树形 \(dp\) . \(f[i][j]\) 代表 \(i\) 为根的子树 ,\(i\) 涂 \(j\) 号颜色的方案数. 转移很显然 : \[f[i][1]= ...
- Xcode编辑器之快捷键的使用
一,快捷键图标 图标 键盘 ⌘ Command ⌃ Control ⌥ Option ⇧ Shift 二, 常用快捷键 文件快捷键 快捷键 键盘 描述 ⌘N command + N 新文件 ⇧⌘N ...
- mysql错误日志及sql日志的区别
my.ini # power by phpStudy 2014 www.phpStudy.net 官网下载最新版 [client] port=3306 [mysql] default-characte ...
- 【HDOJ6659】Acesrc and Good Numbers(dfs)
题意:定义f(n,d)为数码d在1到n中出现的次数,其中d=0..9 如果f(d,k)=k,则称k是d好数 给定x和d,求不大于x的最大的d好数 x<=1e18 思路:考虑f的增长率主要和位数有 ...
- Log4j log for java(java的日志) 的使用
log4j的使用,Log4j log for java(java的日志) 是java主流的日志框架,提供各种类型,各种存储,各种格式,多样化的日志服务. 可以再Apache官网下载得到. 我们下载lo ...
- TODO 思维模型 尺子 游标卡尺
100个人 两个思维切入点 1>做对的题怎么分配 m(x)表示答对x道题的最多人数f(x)表示答对x道题的人数 m(0)=5m(1)=20=>f(0)=0m(2)=m(1)+1=21=&g ...
- QQ空间分享网址
现在大部分网站都在每个界面设计了分享这个功能,但还是有的网页没有(比如 B 站只能分享具体的视频).在原来的 QQ 空间分享的地方已经找不到法自己创建分享.上网一搜有分享的接口,可这个接口是给开发者用 ...