如何判断属性是来自自身对象还是js原型链最上层对象是

本文主要介绍判断JS对象是否拥有某种属性的两种方式,感兴趣的朋友可以借鉴下!
两种方式,稍微有区别
1,in 运算符
复制代码 代码如下:
var obj = {name:'jack'};&
alert('name' in obj); // --& true&
alert('toString' in obj); // --& true&
可看到无论是name,还是原形链上的toString,都能检测到返回true。
2,hasOwnProperty 方法&
复制代码 代码如下:
var obj = {name:'jack'};&
obj.hasOwnProperty('name'); // --& true&
obj.hasOwnProperty('toString'); // --& false&
原型链上继承过来的属性无法通过hasOwnProperty检测到,返回false。
需注意的是,虽然in能检测到原型链的属性,但for in通常却不行。
当然重写原型后for in在IE9/Firefox/Safari/Chrome/Opera下是可见的。
最新图文资讯
相关文章列表:
站长圈推荐文章
 -   -   -   -   -   - 在了解原型链之前需要先知道什么是原型,什么是原型继承。
每一个函数都会有一个prototype属性,当然也就包括构造函数这种特殊的函数在内,我们可以把整个prototype就叫做原型。
2.原型继承
在js中原型继承是实现继承的一种方式,其他的实现继承的方式还有使用call函数apply函数等。实现原型继承的方式是将上级函数实例赋值给下级函数的原型。
在js中由于原型继承的关系,就会产生一种叫做原型链的东西,那么到底什么是原型链呢?
& & &原型链:简单来说就是函数原型通过继承关系联系在一起,形成的链式结构就被叫做原型链。简单来说就是在实现原型继承的时候,会将下级函数的原型和上级函数的实例联系起来,那么多个构造函数相互继承,将彼此的原型联系起来就形成了原型链。
4.原型链中对象属性的查找规则
在原型链中,我们想要查找某一个对象的属性,如果该属性在当前对象所在的函数中查找,如果没有的话就会沿着原型链向上查找,找到的话就返回属性值,如果都没有的话就会返回undefined。举个例子
//原型链中属性的查找
function Person(name,color){
this.name=
this.color=
function Teacher(name,age){
this.name=
//实现继承
Teacher.prototype=new Person();
Teacher.prototype.book=&书本&;
var t1=new Teacher(&aa&,32);
//查找属性
//1.当Teacher中含有name属性,不管有没有赋值都表明在Teacher中含有name属性
console.log(t1.name);
//2.当查找Teacher中没有的属性的时候,但是Teacher的原型中有该属性
console.log(t1.book);
//3.当查找Teacher原型和本身都没有属性的时候,但是上级函数中有该属性的时候
console.log(t1.color);
以上的三种情况就是一个很明显的利用原型链查找属性的例子,可以写个demo简单实验一下,只要测试过之后肯定能够很清晰的理解啦。
5.在面向对象原型链中常见的函数
1.hasOwnProperty():判断属性是否是自身私有属性,如果是的话返回true,否则的返回false
2.in:判断属性是否可用,不管是自身私有还是原型中的属性,如果可用的话返回true,否则的返回false。
感兴趣的同学可以深究一下这两个函数,这里就不用代码举例子了。
该博客基本介绍了原型链的形成,以及在原型链中如何查找对象属性的问题,还有两个简单的函数。如果该文章能够对您产生帮助那是再好不过的。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1532次
排名:千里之外
原创:34篇精进的前端(15)
&&&&&&JS对象查找属性与方法时,除了优先会从自身查找,还会不断追溯自己的原型祖先,自到追溯到Object对象的原型为止。
&&&&&&基于JS对象原型的这种特征,为了保证调用正常,经常需要判断对象之间是否存在原型关系,这里提供两种方法,分别是getPrototypeOf与isPrototypeOf,示例代码如下:
var shapeProto = {
getType () {
return this.type !== undefined ? this.type : 'Shape';
function Shape(type) {
this.type =
Shape.prototype = shapeP
function Circle(radius) {
this.radius =
this.getRadius = function() {
return this.
circleProto = new Shape('Circle')
Circle.prototype = circleP
var c1 = new Circle(10);
alert(c1.getType());
&&&&&&现在,Circle对象的原型链为circleProto =& shapeProto =& Object.prototype,查找属性与方法时会依次往上查找,为了判断对象之间的原型依赖关系,可以采用如下的方法。
1.getPrototypeOf,用于查找原型链的直接父原型
alert(Object.getPrototypeOf(c1) === circleProto);
alert(Object.getPrototypeOf(c1) === shapeProto);
&&&&&&利用getPrototypeOf的这个特性,我们可以轻松获得对象的原型链,如下:
function getPrototypeChain(obj) {
var result = [],
while(proto != null) {
proto = Object.getPrototypeOf(obj);
if(proto != null) {
result.push(proto);
var protoChain = getPrototypeChain(c1);
2.isPrototypeOf,能对原型链上的所有对象进行判断
alert(circleProto.isPrototypeOf(c1));
alert(shapeProto.isPrototypeOf(c1));
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:90459次
积分:2363
积分:2363
排名:第14610名
原创:153篇
评论:11条
(13)(6)(2)(12)(19)(19)(3)(21)(37)(23)(1)原型和原型链的总结_谷祖楠_新浪博客
原型和原型链的总结
这篇要问自己几个问题:
1.对象有分类吗?对象的分类是什么?
虽然说在javascript中所有一切都是对象,这不假,但是对象和对象还是不一样的,产生对象的方法有这几种。
1)直接通过new Object生成“名正言顺”的对象实例。这个对象实例将继承所有来自Object
对象的属性和方法(包括Object对象的原型对象,这是后话。稍作了解即可)。
2)通过编写构造函数,然后再new一个自定义函数。​这个也不难理解,系统给的毕竟有些属性和方法不是符合程序员的心意,所以会自定义一个函数,其声明方法就和声明一个函数一样。
function Foo(){
this.i =0;
}//这个函数现在正是可以称作构造函数啦,你说什么?我没有逗你,虽然只是比普通函数名​多了一个首字母大写,但在程序员心中这就是一个构造函数了,可以拿着这个构造函数愉快的创建以它为模板的对象实例。方法和用new
Object一样,var foo = new Foo();
这样一个构造函数就变成了对象模板。
这就是那句老话,js里所有都是对象,函数是对象,对象是对象,而js又是函数编程,基本脱离不了函数(对象)。
​有了这个基础,我们再来看看js这个活雷锋帮我们内置了什么功能强大的东东吧!
js有很多内置构造函数,他将常用的方法属性封装好放入构造函数里,这个构造函数都是可以直接调用,例如Math,他是一个包含很多数学方法的构造函数,使用的时候可以Math.ceil(6.3)//向上取整​,
var tt = new Date();//取当前系统时间。
这里有个小疑问,为什么不用new一个对象呢?​
原生函数的行为是ECMAScript标准规定的(函数对象的[[Construct]]),由JS引擎负责实现标准。同一原生的构造函数,是否通过new关键字调用可能具有不同的行为(如Date、String、Boolean、Number函数),也可能具有相同行为(如Object、RegExp、Array)。有的原生构造函数必须使用new关键字(如Promise、Proxy、Set、Map、ArrayBuffer),也有的一定不能使用new关键字(如Symbol)
作者:郑航链接:/question//answer/来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。​
暂时没有验证上述答案的正确性,姑且作为参考。​
这些都是js在他内部已经定义好的,可以直接调用,当然可以任性。​
2.原型是什么?
​首先,最重要的就是要知道,原型也是一个对象。不难理解吧,因为js中啥都是对象。
说到原型,我们要扯一下为什么要有原型这个东西,俗话说的好,所有的事物不会凭空产生。原型诞生的​意义就是可以实现代码复用。
我们平时生成的对象基本都是通过构造函数实现的,既然是通过构造函数实现,那么就​
function Foo1(){
this.a=function(){
return 15;
var foo = new
var foo1 = new
好,我们已经通过Foo1()
这个构造函数生成了两个对象实例,不用猜每个对象实例中都有一套构造函数里的内容,如果foo1
不需要这些属性呢?这是什么?浪费内存啊,这是在作死啊!
你每new一个Foo1就相当于说你在内存中又开辟了一块地方存储了Foo1里的所有属性和方法。不能忍。所以呢,原型应运而生。
原型出现的目的就是把需要共享的​​属性方法放到一个对象里,这个对象就是原型(对象)。
既然我们知道了原型的来历和本质,我们再来探究一下原型和构造器的联系。​
我们通过prototype属性可以为任意一个构造函数添加原型属性和方法:
​function
& &this.i = 1;
Foo2.prototype.m =
0;​//prototype属性就是一个可以让构造函数往原型中添加属性方法的方法。
var foo2 = new
Foo2();​
这样就把m属性加入到构造函数Foo2的原型中去。
m并没有在Foo中定义,但是通过new关键字生成的foo2仍然可以访问m,充分说明有一个机制让实例去在构造函数之外继续搜索m这个变量,而这个函数之外的区域就是原型对象。机制:当实例想要访问一个变量的时候,他会首先搜索构造函数,没有就去搜索他的原型对象,如果还没有呢?继续向上,搜索原型链的上游,但是都没有呢,返回undefined
这个图就充分说明了变量的搜索机制。
3.ECMAscript中的内置构造函数(器)的本质是什么?
​内置的构造函数例如(Array Date
String等等),他其实和普通的构造函数一样,也是内部通过function
Array(){}生成的。那他本质上也是一个函数。
4.原型链是什么?
5.构造函数和原型的关系?
构造函数里有一个属性prototype,这个属性里面存储着它原型对象的指针。这样构造函数就能找到原型对象。​反过来,原型对象也有一个属性,constructor。这个属性指向构造函数的指针。这样就可以互相“认识”。​
6.通过构造函数生成的实例对象与原型的关系?
7.__proto__是什么?​
​在JS里,万物皆对象。方法(Function)是对象,方法的原型(Function.prototype)是对象。因此,它们都会具有对象共有的特点。即:对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。
作者:doris链接:/question//answer/来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
​8.__proto__和prototype之间的关系或区别是什么?
方法(Function)方法这个特殊的对象,除了和其他对象一样有上述_proto_属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。&
另一种写法
上图中的知识点:
1.构造函数Foo()构造函数的原型属性Foo.prototype指向了原型对象,在原型对象里有共有的方法,所有构造函数声明的实例(这里是f1,f2)都可以共享这个方法。
2.原型对象Foo.prototypeFoo.prototype保存着实例共享的方法,有一个指针constructor指回构造函数。
3.实例f1和f2是Foo这个对象的两个实例,这两个对象也有属性__proto__,指向构造函数的原型对象,这样子就可以像上面1所说的访问原型对象的所有方法啦。另外:构造函数Foo()除了是方法,也是对象啊,它也有__proto__属性,指向谁呢?指向它的构造函数的原型对象呗。函数的构造函数不就是Function嘛,因此这里的__proto__指向了Function.prototype。其实除了Foo(),Function(),
Object()也是一样的道理。原型对象也是对象啊,它的__proto__属性,又指向谁呢?同理,指向它的构造函数的原型对象呗。这里是Object.prototype.最后,Object.prototype的__proto__属性指向null。
1.对象有属性__proto__,指向该对象的构造函数的原型对象。
2.方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。
3.__proto__是站在对象的角度讨论原型对象。
4.prototype是站在构造函数的角度讨论原型属性,或构造函数创建的对象的原型对象。​
博客等级:
博客积分:0
博客访问:1,284
关注人气:0
荣誉徽章:问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
var obj1 = {name:'one'};
obj2 = Object.create(obj1);
obj2.name = 'two';
console.log(obj1.name);
var obj1 = {prop:{name:'one'}};
obj2 = Object.create(obj1);
obj2.prop.name = 'two';
console.log(obj1.prop.name);
var obj1 = {list:['one','one','one']};
obj2 = Object.create(obj1);
obj2.list[0] = 'two';
console.log(obj1.list[0]);
为什么后面两段代码修改的是原型链上的属性呢?
问题是,为什么二、三中的代码不是像代码一中直接给obj2添加属性,而是修改了原型链上的属性?求解释下一、二、三的结果?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
简单的说,一是给对象的属性赋值,相当于给obj2 增加了一个叫做name的属性,而二和三则是修改对象原型上的属性。
对象的原型也是一个对象,所以它是一个引用的关系,修改原型相当于修改原来的对象。
对象的get有一个优先级的情况,比如,你要获取一个对象的name属性,首先从对象自身开始查找,如果自身没有,则开始查找原型链。
PS:如果题主还是不理解,我可以再换一个方式回答。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
Object.create方法指定的第1个参数为新建对象的原型对象
在获取一个对象的属性值时,才会有可能沿着原型链向下寻找,属性赋值没有这个
给一个对象属性赋值时,如果这个属性不存在,那么就直接为这个对象添加这个属性并赋值(不会去理会原型链中的存在,除了某些特殊情况,如原型链中有这个属性的set方法,或这个属性被设置只读不可写的)
obj2.prop.name='two' 先计算obj2.prop的值,在原型链中被发现,然后再计算obj2.prop对应的对象(不检查原型链)中是否存在name属性~~~
obj2.list[0] = 'two';
也就是先计算obj2.list属性的值,然后赋值给obj2.list属性下标为0(属性名为“0”)的属性
那么结果就好理解了吧
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
扫扫下载 App

我要回帖

更多关于 js原型链最上层对象是 的文章

 

随机推荐