原型对象,继承
1、原型--Prototype
对象有什么区别?
函数对象和普通对象
prototype是函数对象才有的属性
_proto_是每个对象都有的属性
通过new Function函数对象
function f(){} ==>var f = new Function(); funcition f(){}//函数对象 console.log(typeof f);//function var o = {}//普通对象 console.log(typeof o)//object var o2 = new f()//函数实例是普通对象 console.log(typeof o2)//object //重点: //1、每一个函数对象都有prototype属性,普通对象没有 prototype下面有个constructor,指向这个函数 //2、每一个对象都有一个_proto_属性;指向它所对应的构造函数的原型对象 //检测 var o3 = {}//o3 = new Object(); console.log(o3.prototype) console.log(o3 instanceof Object)//实例o3在不在Object构造函数中 function Demo(){} //函数对象 var d = new Demo(); //普通对象 console.log(d.prototype) //undefined console.log(d instanceof Demo)
2、普通对象和函数对象
//原型对象 function Person(){} //构造函数 Person.prototype.name = 'abc'; Person.prototype.action= function(){}; var p1 = new Person(); var p2 = new Person(); var p3 = {} p3.name='p3'; p3.age=18; var p4 = {}; p4.name='p4'; p4.age=16; //缺点:写起来麻烦,生成了多个实例,实例间没有任何的关系 //创建公共的方法 缺点不能反映出它们是同一个原型对象的实例 function p(name,age){ return { name:name, age:age } }; var p5 = p('a',20); var p6 = p('b',22); p5.name; //构造函数 function Cat(name,color){ this.name = name; this.color = color; this.type = '动物'; this.eat = function() { console.log('吃老鼠') } }; var cat1 = new Cat('大明','黑色'); var cat2 = new Cat('小明','白色'); 缺点:公共的部分占用内存
//原型对象 function Cat(name,color){ //构造函数 this.name = name; this.color = color; // this.type = '动物'; // this.eat = function() { // console.log('吃老鼠') // } }; Cat.prototype.type = '动物'; Cat.prototype.eat = function() { console.log('吃老鼠') } var cat1 = new Cat('大明','黑色'); var cat2 = new Cat('小明','白色'); //验证 //in 无论是自身的还是原型属性都返回true console.log('name' in cat1) ;//true console.log('type' in cat1) ;//true //hasOwnProperty() 自身的属性返回true 原型属性返回false console.log(cat1.hasOwnProperty('name')); //true console.log(cat1.hasOwnProperty('type')); //false
3、继承
//继承 function Animal(){ //一个对象 父对象 this.type = '动物'
}; function Cat(name,color){ //另一个对象 子对象 this.name = name; this.color = color; }; //实现‘猫’与‘动物’对象继承 //1、call() apply() 在一个对象中调用另一个对象 call() apply(this,参数) //区别 参数不同, apply 传数组 call 一个个传; function Animal(){ //一个对象 父对象 this.type = '动物' }; function Cat(name,color){ //另一个对象 子对象 Animal.apply(this); //Animal在当前cat对象中执行 将父对象的构造函数绑定到子对象上 this.name = name; this.color = color; }; var cat1 = new Cat('大毛','黄色'); cat1.type; //'动物' //直接继承 function Animal(){ //一个对象 父对象 this.type = '动物' }; function Cat(name,color){ //另一个对象 子对象 this.name = name; this.color = color;
}; Cat.prototype = new Animal(); var cat1 = new Cat('大毛','黄色'); cat1.type; //'动物'
//优化 function Animal(){ //一个对象 父对象 // this.type = '动物' }; Animal.prototype.type = '动物'; function Cat(name,color){ //另一个对象 子对象 this.name = name; this.color = color; }; Cat.prototype = Animal.prototype; //缺点: Cat.prototype和Animal.prototyper指向同一个对象 //当修改Cat.prototype的值时,Animal.prototype也会变化 Cat.prototype.abc = 'abc'; var cat1 = new Cat('大毛','黄色'); cat1.type; //'动物' console.log(Animal.prototype);