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);