javascript 中isPrototypeOf 、hasOwnProperty、constructor、prototype等用法
hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。
isPrototypeOf是用来判断要检查其原型链的对象是否存在于指定对象实例中,是则返回true,否则返回false。
instanceof 操作检查对象中是否有名为 property 的属性。也可以检查对象的原型,判断该属性是否为原型链的一部分.
Java代码
hasOwnProperty:
var obj = {a:1,b:2}
obj.hasOwnProperty('a')
isPrototypeOf:
function F(){}
var fn = new F()
F.prototype.isPrototypeOf(fn)
前者是判断对象中是否存在某个属性,后者是判断对象是否是原型链的对象。
JavaScript中isPrototypeOf函数方法是返回一个布尔值,指出对象是否存在于另一个对象的原型链中。使用方法:
object1.isPrototypeOf(object2)
其中object1为必选项,一个对象的实例。
object2为必选项,另一个对象,将要检查其原型链。
如果 object2 的 原型链中包含object1,那么JavaScript中isPrototypeOf函数方法返回 true。
原型链可以用来在同一个对象类型的不同实例之间共享功能。
如果 object2 不是一个对象或者 object1 没有出现在 object2 中的原型链中,
JavaScript中isPrototypeOf函数方法将返回 false。
以下示例阐述了JavaScript中isPrototypeOf函数方法的用法。
function test(){
var re = new RegExp(); //初始化变量。
return (RegExp.prototype.isPrototypeOf(re)); //返回 true。
}
constructor:对象构造器。
prototype:访问对象构造器的原型,只有函数才具有这个属性。
isPrototypeOf:如果对象 A 存在于 对象obj的原形链中,则 A.isPrototypeOf(obj)返回true,而obj必定继承了A 的属性。
__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();
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,但是在最新的浏览器已经可以了,包括 IE 9.
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
instanceof:如果obj对象是构造函数Fun的一个实例,则 obj instanceof Fun 返回 true,值得注意的是,instanceof 并不检查 Fun 函数,而是检查 Fun.prototype,是基于"原形链"的,因此,即使 obj instanceof Fun 返回 true,obj 也可能不具有 Fun 构造器中定义的属性,因为 Fun 不一定是 obj 的构造器。
function Bar(){}
function A(){}
Bar.prototype = new A();
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,(不相同的对象不会相等)*/
关于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 的对象原型已经是女娲级的了
javascript 中isPrototypeOf 、hasOwnProperty、constructor、prototype等用法的更多相关文章
- JavaScript中isPrototypeOf函数
转自:http://www.ijavascript.cn/shouce/javascript-isprototypeof-247.html JavaScript中 isPrototypeOf 函数方法 ...
- 深入了解JavaScript中基于原型(prototype)的继承机制
原型 前言 继承是面向对象编程中相当重要的一个概念,它对帮助代码复用起到了很大的作用. 正文 Brendan Eich在创建JavaScript时,没有选择当时最流行的类继承机制,而是借鉴Self,用 ...
- JavaScript中instanceof与typeof运算符的用法及区别详细解析
JavaScript中的instanceof和typeof常被用来判断一个变量是什么类型的(实例),但它们的使用还是有区别的: typeof 运算符 返回一个用来表示表达式的数据类型的字符串. typ ...
- Javascript中的继承与Prototype
之前学习js仅仅是把w3school上的基本语法看了一次而已,再后来细看书的时候,书中会出现很多很多没有听过的语法,其中一个就是js的继承以及总能看到的prototype.我主要在看的两本js书是&l ...
- JavaScript中call,apply和prototype
[TOC] call()方法 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 如果没有提供 thi ...
- javascript中的this与prototype,原型理解
JavaScript 函数调用 JavaScript 函数有 4 种调用方式. 每种方式的不同方式在于 this 的初始化. this 关键字 一般而言,在Javascript中,this指向函数执行 ...
- JavaScript中Function原型及其prototype属性的简单应用
大家都知道在JavaScript中是没有类的概念的,但是却是有对象的概念的.有的人可能理解对象和类有些迷糊,这里简单的概括一下他们之间的区别: 类:抽象的概念,例如人,动物,汽车等都可以抽象成一个类 ...
- javascript中的常用表单事件用法
下面介绍几种javascript中常用的表单事件: 一,onsubmit:表单中的确认按钮被点击时发生的事件,如下案例. 案例解析:弹出表单中提交的内容 <form name="tes ...
- javascript中的hasOwnProperty和isPrototypeOf
hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象.不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员.isPrototypeOf ...
随机推荐
- 我在项目中运用 IOC(依赖注入)--入门篇
之前就听同事说过依赖注入(dependency injection).控制反转(Inversion of Control).起初听的是一头雾水,试着在项目中运用了几次,总算明白了一些,抛砖引玉,与大家 ...
- 使用IDEA工具配置和运行vue项目(详细其中的坑)
刚来公司实习发现公司的前端使用的是vue,之前根本就没有听说过.然后一上来就需要看代码,but but 就是没有文档什么的东西, 就需要自己去研读,我就想去运行其中的前端和后端联调起来方便理解,结果在 ...
- Access restriction: The type BASE64Encoder is not accessible due to restrict(转载)
Access restriction: The type BASE64Encoder is not accessible due to restrict 2011年11月18日 20:47:06 阅读 ...
- 为什么java需要序列化对象
序列化是一种用来处理对象流的机制 所谓对象流:就是将对象的内容进行流化,可以对流化后的对象进行读写操作,也可将流化后的对象传输与网络之间 序列化是为了解决在对象流进行读写操作时所引发的问题 序列化的实 ...
- spring Boot的配置
一.配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的: application.properties application.yml 配置文件的作用:修改SpringBoot自 ...
- IDEA 构建为了打 jar 包的工程,包含 maven 打 jar 包的过程
前言:最近自己写了一个单表查询的组件,包含前端.后台,所以需要向阿里的 druid 一样将所有文件打到一个 jar 包里,这里首先记录如何打 jar 包. 附:自己的一个 jar 包源码 https: ...
- Code Signal_练习题_reverseParentheses
You have a string s that consists of English letters, punctuation marks, whitespace characters, and ...
- async 配合mysql
async-db.js const mysql = require('mysql') const pool = mysql.createPool({ host : '127.0.0.1', user ...
- 使用HttpGet协议与正则表达实现桌面版的糗事百科
写在前面 最近在重温asp.net,找了一本相关的书籍.本书在第一章就讲了,在不使用浏览器的情况下生成一个web请求,获取服务器返回的内容.于是在网上搜索关于Http请求相关的资料,发现了很多资料都是 ...
- DOM节点树和元素树--深度遍历
我们在阅读JS高级程序设计的时候,提到了节点树的概念.比如说: elem.parentNode---找elem的父节点: elem.childNodes---找elem的所有的直接子节点: elem. ...