基本概念
1、通过同一个构造函数创建的对象都会关联一个神秘的对象,可以通过构造函数.prototype进行访问,这个神秘对象被称为原型对象
2、这个原型对象可以被用来做继承用,js中的继承有好几种,包括混入继承,经典继承,还有原型继承
3、通过构造函数创建出来的对象,不仅拥有构造函数中的属性,还拥有原型对象中创建出来的属性
4、实例化后的对象也可以通过__proto__进行访问原型对象,但是只是调试时使用,不推荐正式代码中使用
原型基本
<script> function Person(name, age) { this.name = name; this.age = age; } //不仅拥有构造函数中的属性,还拥有原型中创建出来的属性 Person.prototype.gender = ‘male‘; var p = new Person(‘qx‘, 18); console.log(p.name);//qx console.log(p.age);//18 console.log(p.gender);//male </script>
混入继承
<script> var o = {} var obj = { name: "张三", age: 18, sayHello: function () { console.log("Hello world"); } } //混入式继承 for (var k in obj) { o[k] = obj[k]; } console.log(o); </script>
经典继承
1、最早的原理
<script> //通过替换原型,使得被创建出来对象也拥有传入对象的属性 function jicheng(obj) { var o = {}; o.__proto__ = obj; return o; } var o = jicheng({name: "张三"}); console.log(o); </script>
2、create方法
<script> var o = { name: "周三" }; var obj = Object.create(o); console.log(obj.name); </script>
3、create方法存在兼容性问题
<script> var obj = { name:"周三" }; //检测浏览器的能力,如果没有Object.create方法就给他添加一个(不推荐使用) if(Object.create){ var o = Object.create(obj); }else{ Object.create = function () { function F() { } F.prototype = obj; var o = new F(); } var o = Object.create(obj); } </script>
<script> //自己定义个函数 function create(obj) { if (Object.create) { return Object.create(obj); } else { function F() { } F.prototype = obj; return new F(); } } </script>
原型继承
<script> function Animal() { this.eat = ‘chifan‘; } var animal = new Animal(); function Person() { this.read = ‘dushu‘; } //person显示是具有animal的属性,毕竟人也是动物,具体方法是让person的原型被替换成animal //替换后,通过person构造函数创建出来的对象,不仅具有person的属性,还具有animal的属性 Person.prototype = animal;//Person.prototype = new Animal()这样也行 var p = new Person(); console.log(p.read);//chifan console.log(p.eat);//dushu </script>
复杂原型继承
<script> //动物--->人---->老师---->坏老师 //原型的直接替换会将原型的构造函数也替换了,所以最好重新指定 function Animal() { this.gender = "male"; } Human.prototype = new Animal(); Human.prototype.constructor = Human; function Human() { this.actionWay = "走路"; } Teacher.prototype = new Human(); Teacher.prototype.constructor = Teacher; function Teacher() { this.skill = "教书"; } BadTeacher.prototype = new Teacher(); BadTeacher.prototype.constructor = BadTeacher; function BadTeacher() { this.name = "吕超"; } var t = new BadTeacher(); console.log(t); </script>
原型链基本概念
1、每个构造函数都有原型对象
2、每个对象都会有构造函数
3、每个构造函数的原型都是一个对象
4、那么这个原型对象也会有构造函数
5、那么这个原型对象的构造函数也会有原型对象
6、这样就会形成一个链式的结构,称为原型链
7、通过修改原型链结构实现的继承,就叫做原型继承
属性搜索基本原则
1、当访问一个对象的成员的时候,会现在自身找有没有,如果找到直接使用,
2、如果没有找到,则去当前对象的原型对象中去查找,如果找到了直接使用
3、如果没有找到,继续找原型对象的原型对象,如果找到了,直接使用
4、如果没有找到,则继续向上查找,直到Object.prototype,如果还是没有,就报错