javascript 原型链详解 prototype和__proto__

我对原型链的理解就像是家谱,父-爷-太爷-----祖宗一样的家谱;但还不完全等同家谱,当一个函数或对象产生(或者说我们创建了一个对象或函数),就在原型链上产生了一个对应的存储空间,这个空间存放了这个函数或这个对象的所有内容,,,一般情况下我们调这个对象的某个属性时,这个对象会自行去原型链查找我们需要的东西,当他自身的原型链上没有我们需要的东西她就会去他的父级寻找,以此类推,如果我们实例化一个对象时,那么这个 对象的实例 和原对象的关系要通过原型链保持连接,换句话理解就是,父亲和儿子的关系是通过家谱或者理解为一个特殊的媒介才能保持联系,并相互影响;

谈到原型链就是在讲继承,在继承中,Javascript 只有一种结构:对象。每个对象都有一个私有属性(称为[[Prototype]]),它持有一个连接到另一个称为其 prototype 对象的链接。该原型对象具有一个自己的原型,该原型还有上一级的链接,直到达到一个对象的 prototype 为 null。根据定义,null 没有 prototype,并作为这个原型链 中的最后一个环节。
JavaScript中几乎所有的对象都是位于原型链顶端的 Object 的实例。
下面看一个原型链中 一张很经典的原型链图:



可以理解为prototype为函数才有的属性__proto__是每个对象的属性(但__proto__属于 非标准属性,对应的标准属性为[Prototype] ),prototype的原型可以理解为原始、根、父类型。
__proto__示例

__proto__示例1
function Foo(){this.name="ranning"};var
f1=new Foo();
f1.__proto__.say=function(){
console.log("Hello")};
f1.say();// Hello
//对比上图f1的__proto__的原型链添加方法,f1可以调用这个很好理解;
__proto__示例2
function Foo(){this.name="ranning"};var
f1=new Foo();
Foo.__proto__.say=function(){
console.log("Hello")};
f1.say();//f1.say is not a function

Foo的__proto__的原型指向Function prototype,Foo的__proto__的原型链Foo.prototype指向(继承)Objective的原型链(Object prototype),和Function prototype,无直接关系,所以f1无方法,于是我们做下面的示例3
__proto__示例3
function Foo(){
this.name="ranning"
};
var a=new Foo();
Foo.__proto__.__proto__.say=function(){
console.log("Hello")
};
a.say();//Hello
Foo的__proto__的原型指向(继续)Function prototype,(Foo.__proto__==Function prototype;Foo.__proto__.__proto__==Object.prototype),Foo的__proto__的原型链Foo.prototype指向(继承)Objective的原型链(Object prototype)所以。。。。
特别注意:以上示例示例只是帮助理解__proto__的含义以及图形的意义,正常不会使用这个属性。

prototype示例


prototype示例1
function Foo(){
this.name="ranning"
};
var a=new Foo();
Foo.prototype.say=function(){console.log("Hello")};
a.say();// Hello//
prototype示例2
function Foo(){
this.name="ranning"
};
var a=new Foo();
Object.prototype.say=function(){
console.log("Hello")
};
a.say();// Hello

丛上面的例子中可以看出prototype的实例对象是没有这个属性,在w3school中介绍: prototype 属性使您有能力向对象添加属性和方法。

func.__proto__不应该与函数的func.prototype属性相混淆,而是指定在作为构造函数使用给定函数创建的对象的所有实例时分配的[[Prototype]]。Object.prototype属性表示 Object 的原型对象。





原型链相关属性及方法

在原型链上查找属性比较耗时,对性能有副作用,这在性能要求苛刻的情况下很重要。另外,试图访问不存在的属性时会遍历整个原型链。
遍历对象的属性时,原型链上的每个可枚举属性都会被枚举出来。
检测对象的属性是定义在自身上还是在原型链上,有必要使用  hasOwnProperty  方法,所有继承自  Object.proptotype 的对象都包含这个方法
hasOwnProperty  是 JavaScript 中唯一一个只涉及对象自身属性而不会遍历原型链的方法。
确定某个对象是否具有带指定名称的属性。
object.hasOwnProperty(proName)
object:  必需。对象的实例。
proName:  必需。一个属性名称的字符串值。

特别注意:
function Foo(){
this.name="ranning"
};
var a=new Foo();
Foo.prototype.say=function(){
console.log("Hello")
};
此时Foo.hasOwnProperty("say");//false;
Foo.prototype.hasOwnProperty("say");//true;



isPrototypeOf():

The  isPrototypeOf()  method checks if an object exists in another object's prototype chain.
isprototypeof()方法检查对象是否存在于另一个对象的原型链。
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);
var baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

   
   
    
    


    
    


    
    


    
    


    
    


    
    


    
    


    
    


    
    


    
    


    
    


    
    


   
   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
prototype和__proto__都与JavaScript中的原型链相关。 1. prototype是一个函数特有的属性,它指向一个对象,该对象是使用该函数作为构造函数创建的所有实例的原型。通过原型链,实例可以访问构造函数的原型中定义的属性和方法。 例如,我们有一个构造函数Person: ```javascript function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log('Hello, ' + this.name + '!'); }; var person1 = new Person('Alice'); person1.sayHello(); // 输出 "Hello, Alice!" ``` 在上面的例子中,Person.prototype是一个对象,它包含了我们想要共享给所有Person实例的属性和方法。 2. __proto__是每个对象都有的属性,它指向该对象的原型。通过__proto__,对象可以访问自己的原型中定义的属性和方法。 例如,我们再使用上面的Person构造函数创建一个person2对象: ```javascript var person2 = new Person('Bob'); person2.sayHello(); // 输出 "Hello, Bob!" ``` 在上面的例子中,person2.__proto__指向Person.prototype,这样person2就可以调用Person.prototype中定义的sayHello方法。 虽然__proto__属性在现代JavaScript中已经被废弃,但仍然可以在一些老旧的浏览器和环境中使用。推荐使用Object.getPrototypeOf()来获取对象的原型,例如: ```javascript var proto = Object.getPrototypeOf(person2); proto === Person.prototype; // true ``` 总结:prototype是构造函数的属性,指向构造函数的原型对象;而__proto__是每个对象都有的属性,指向该对象的原型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值