JS原型链

JS面向对象中的原型
每一个构造函数都有一个属性 即原型对象(prototype)同时每一个原型对象(prototype)都有一个属性(constructor)指向构造函数,同时每一个对象又有一个__proto__的非标准属性,这个属性指向构造函数的原型对象。
理解上面概念,引入“原型链”
如下新建一个构造函数

function Student(name,sex,age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}

在这里插入图片描述

打印这个构造函数,发现其具有prototype属性,这个属性就是构造函数的原型对象,同时这个原型对象有具有一个属性constructor属性,这个属性指向构造函数

实例化构造函数

var stu1 = new Student('te','m',12);
 console.dir(stu1);

在这里插入图片描述
打印结果,印证上面所说的每一个对象又有一个__proto__属性,这个属性是指向构造函数的原型对象的所以proto ==构造函数的prototype

 console.log(stu1.__proto__ === Student.prototype)
 //返回true

综上我们可以得出 构造函数 原型对象 以及对象之间的关系
如图
在这里插入图片描述
对象通过构造函数创建,而每一个对象有一个__proto__属性,这个属性是指向原型对象的,而每一个原型对象又有一个constructor属性,这个属性指向构造函数,上面说到每一个构造函数具有一个prototype属性,这个属性就是原型对象
由此可以得到一个简单得三角关系。
如果你仔细观察可以发现原型对象也有一个__proto__属性,这并不奇怪,因为每一个对象都有一个__proto__属性这个属性是指向他构造函数的原型对象。
查看原型对象的指向
在这里插入图片描述
可以看到原型对象的__proto__属性(这个属性指向Object的原型对象)里面的constructor属性指向其构造函数Object
那么原型对象也是由构造函数创建,这个构造函数就是Object。上面说到只要是对象就会有一个__proto__属性,这个属性指向构造函数的的原型对象,那么Object的原型对象的原型对象又是什么呢?

 var stu1 = new Student('te','m',12);
 var o = stu1.__proto__;
 console.log(o);//构造函数的原型对象
 console.log(o.__proto__.__proto__);//Object的原型对象的原型对象

在这里插入图片描述
可以看到Object的原型对象的原型对象为空null那么null有原型对象吗,会不会一直循环下去?

   console.log(o.__proto__.__proto__.__proto__);//null的原型对象

在这里插入图片描述
抛出异常,说明最顶层的原型对象就是null,因此我们可以得出一个简单的原型链图
在这里插入图片描述
我们通过构造函数创建一个对象,因为每一个对象有一个__proto__属性,这个属性就指向该对象构造函数的原型对象,由于原型对象也有一个__proto__属性,这个属性指向原型对象的原型对象,我们可以看到原型对象的原型对象的构造函数为Object而原型对象是具有__proto__属性的,而Object的原型对象的原型对象指向null所以我们说最顶层的原型对象为null

说了那么多根据原型链我们可以得出对象查找/设置属性和方法的规则

结论

查找:对象在调用属性或方法时,会先在当前对象查找是否有相关属性或方法
如果没有就在当前对象的构造函数的原型对象上查找,如果还是没有则继续在原型对象的原型对象上查找直到指向null这就是我们所说的原型链。
如下

function Student(name,sex,age){
		this.name = name;
		this.sex = sex;
		this.age = age;
		this.method = function(){
			console.log(123)
		}
	}//构造函数
	Student.prototype.method=function(){
		console.log(321)
	}

   var stu1 = new Student('te','m',12);
   stu1.method()
 

我们分别在原型对象和构造函数中写入了相同的方法,结果输出123
如果我们将构造函数中的method方法去掉则会调用原型对象上的方法输出321
同时我们可以原型链的查找规则使用Object中的属性或方法,以toString为例

 console.log(stu1.toString());
 //返回[object Object]字符串

设置:对象在设置属性/方法时,如果当前对象没有该属性或方法,则重新在当前对象创建一个同名属性/方法,并不会影响原型链上具有的属性或方法

function Student(name,sex,age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}//构造函数
	Student.prototype.method=function(){
		console.log(123);
	}

   var stu1 = new Student('te','m',12);
   stu1.method=function(){
   	console.log(321)
   }
  
   var stu2 = new Student('w','w',13);
   stu1.method();
   stu2.method()
   // console.dir(

在这里插入图片描述
可以看到stu1并没有修改原型链上的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值