js-原型链
今天我们来了解一下JavaScript最神秘最可爱的地方 😄哈哈!!
在谈原型链之前,我们首先要了解自定义函数与 Function 之间是什么关系,而构造函数、原型和实例之间又存在什么千丝万缕的关系呢?其实,所有的函数都是 Function 的实例。在构造函数上都有一个原型属性 prototype,该属性也是一个对象;那么在原型对象上有一个 constructor 属性,该属性指向的就是构造函数;而实例对象上有一个 _proto_ 属性,该属性也指向原型对象,并且该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用。
每个实例对象(object )都有一个私有属性(称之为 __proto__)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象 ,层层向上直到一个对象的原型对象为 null
。根据定义,null
没有原型,并作为这个原型链中的最后一个环节。
几乎所有 JavaScript 中的对象都是位于原型链顶端的Object
的实例。
1 <script> 2 //动物--->人---->老师---->坏老师 3 4 function Animal(){ 5 this.gender = "male"; 6 } 7 8 Human.prototype = new Animal(); 9 Human.prototype.constructor = Human; 10 11 function Human(){ 12 this.actionWay = "走路"; 13 } 14 15 Teacher.prototype = new Human(); 16 Teacher.prototype.constructor = Teacher; 17 function Teacher(){ 18 this.skill = "教书"; 19 } 20 21 BadTeacher.prototype = new Teacher(); 22 BadTeacher.prototype.constructor = BadTeacher; 23 function BadTeacher(){ 24 this.name = "张三"; 25 } 26 27 var t = new BadTeacher(); 28 console.log(t);
console.log(t.skill); //教书
console.log(t.gender); //male
29 </script>
由于电脑没有安装画图软件,我就手工画了一个示例图。
解释上面红色代码的含义:
原型对象在创建出来的时候,会默认的有一个constructor属性 指向对应的构造函数
在使用新的对象替换掉默认的原型对象之后 ,原型对象中的constructor属性会变成 Object
为了保证整个 构造函数---原型----对象 之间的关系的合理性
应做如下操作:在替换原型对象的时候,在新的原型对象中手动添加 constructor 属性
1、原型链
1)构造函数、原型和实例的关系
①prototype是构造函数的属性
②_proto_是实例对象的属性
——这两者都指向同一个对象
【总结】i)函数也是对象,对象不一定是函数;
ii)对象的本质:无序的键值对集合;键值对当中的值可以是任意数据类型的值
iii)对象就是一个容器,这个容器当中放的是(属性和方法)
3)属性搜索
①在访问对象的某个成员的时候会先在对象中找是否存在
②如果当前对象中没有就在构造函数的原型对象中找
③如果原型对象中没有找到就到原型对象的原型上找
④直到Object的原型对象的原型是null为止
扩充:
Function也可以被当做一个构造函数,通过Function new出来函数可以被当做是实例化的对象,那么Function这个构造函数也有原型对象,Function的原型对象是一个空的函数,Function的原型对象的原型对象是Object.prototype
1 var foo = new Function(); 2 3 console.log(Function.prototype); 4 5 console.log(Function.prototype.__proto__);
下面是Function的原型链
1 function Person(){ 2 3 } 4 var p = new Person();
根据此代码,绘制完整的原型链结构图:
下图能够看出 Object 和 Function 的关系;
Object构造函数 是 通过 Function 构造函数 实例化出来的
Function构造函数 也是 通过 Function 构造函数 实例化出来的(不要强行去理解)
1 instanceof 关键字 2 语法: 对象 instanceof 构造函数 3 判断该构造函数的原型是否存在于该对象的原型链上 4 5 6 // Object.prototype是否在Function的原型链上 7 // Function-->Function.prototype---->Object.prototype---->null 8 console.log(Function instanceof Object); //true 9 10 // Function.prototype是否在Functionde原型链上 11 console.log(Function instanceof Function); //true 12 13 // Object--->Function.prototype---->Object.prototype----->null 14 console.log(Object instanceof Function); //true 15 console.log(Object instanceof Object); //true