JS原型链

1.什么是原型链

范例:

		Grand.prototype.lastName = "Lei";
		function Grand (){}
		var grand = new Grand ();
		Father.prototype = grand ;
		function Father(){
			this.name = "ss"
		}
		var father = new Father ();
		Son.prototype = father;
		function Son(){
			this.hobbit = "sing"
		}
		var son  = new Son();

访问son对象的hobbit属性 能找到hobbit属性
在这里插入图片描述
访问son对象的name属性,son对象自身没有这个属性,就要去其__proto__属性指向的其构造函数Son的原型——father对象上找,能找到name属性
在这里插入图片描述
访问son对象的lastName属性,son对象和其__proto__属性指向的原型对象(也就是father对象)上都没有,就要继续从father对象的__proto__属性指向的原型对象(也就是grand对象)上找,也没有,继续看grand对象的原型Grand.prototype,能找到lastName属性
在这里插入图片描述
像这样,在一个原型身上不断叠加原型,访问顺序依照作用链的访问顺序(从近往远查),把原型连成的链叫做原型链,原型链的连接点就是__proto__。

原型链的终端

Grand构造函数的原型对象是我们已知的能看到的尽头,但并不是真正的尽头,它仍有__proto__属性
JS原型链_第1张图片

Grand.prototype.__proto__ = Object.prototype(绝大多数对象的最终原型)

JS原型链_第2张图片
在这里插入图片描述
可以看到Object.prototype没有__proto__属性,是原型链的终端

在这里插入图片描述
访问son对象的toString方法,返回的是Object.prototype上的toString方法

2.原型链上属性的增删改查(同原型属性的增删查改)

范例:

		Grand.prototype.lastName = "Lei";
		function Grand (){}
		var grand = new Grand ();
		Father.prototype = grand ;
		function Father(){
			this.name = "ss"
		}
		var father = new Father ();
		Son.prototype = father;
		function Son(){
			this.hobbit = "sing"
		}
		var son  = new Son();


不能通过函数创建出来的对象(下面简称子孙)查看原型的属性方法,因为prototype属性是function对象的属性,不是创建出来的对象的属性
JS原型链_第3张图片
用function对象可以查看原型属性方法
JS原型链_第4张图片

子孙都无法访问更不用提增加
function对象可以增
JS原型链_第5张图片


子孙通过delete关键字只能删除自带的属性
JS原型链_第6张图片
而不能删除原型的属性(道理同增加的一样) 即便返回的是true(返回true是因为系统认为删除一个不存在的属性也ok)
JS原型链_第7张图片
function对象可以删除
JS原型链_第8张图片


子孙都无法访问更不用提更改 function对象可以更改

JS原型链_第9张图片


例题1:

现在有这么一道题
代码如下问输出多少?

		Person.prototype = {
			name : "a",
			sayName : function(){
				console.log(this.name);
			}
		}
		function Person (){

		}
		var person = new Person();

答案显而易见
在这里插入图片描述
这样呢?输出为?

		Person.prototype = {
			name : "a",
			sayName : function(){
				console.log(this.name);
			}
		}
		function Person (){
			this.name = "b";

		}
		var person = new Person();

谁调用的sayName()方法,sayName()方法里的this就指向谁
在这里插入图片描述
在这里插入图片描述
例题2:

		Person.prototype = {
			height : 100
		}
		function Person (){
			this.eat = function(){
				this.height++;
			}
		}
		var person = new Person();

问:Person对象调用eat方法后,其原型的height属性值应为多少?
JS原型链_第10张图片
谁调用的eat()方法,eat()方法里的this就指向谁,这里的this指向创建的Person对象,而该对象中没有height属性,系统会帮助创建这个属性,赋值原型中对应的属性值,再进行运算

3.Object.create(原型)创建对象

可以用于创建对象(更加灵活),括号里的原型就是创建出来的对象的原型

		var obj = {name:"ls",age:123}
		var obj1 = Object.create(obj);

JS原型链_第11张图片

		Person.prototype.name = "ls"
		function Person(){}
		var Person = Object.create(Person.prototype)
		           = new Person()

4.绝大多数对象(不是全部对象)最终都会继承自Object.prototype

我们试着创建一个没有原型的对象
在这里插入图片描述
报错:原型只能是一个对象或者null
既然如此我们就创建一个原型为null的对象,可以创建且创建的对象没有原型,故不是所有对象最终原型都是Object.prototype,而是大多数
JS原型链_第12张图片

你可能感兴趣的:(JS)