使用面向对象的方法来创建对象
第一步:使用工厂函数来创建对象
function createPerson(name,age,eat,pao){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.eat = eat
obj.pao = pao
return obj;
}
// 创建张三
var zs = createPerson('张三',12,function(){
console.log("能吃")
},function(){
console.log("每天都跑");
})
//创建小狗阿黄
var ahuang = createPerson('阿黄',2,function(){
console.log("爱吃肉骨头");
},function(){
console.log("闻着味道跑");
});
console.log(zs);
console.log(ahuang);//输出张三和阿黄之后,只能看到两个Object对象,由此可以看出
工厂函数的缺点:无法像数组、字符串、数字等对象一样,能一目了然的看到具体的类型
第二步:优化1
使用自定义的构造函数可以解决工厂函数的缺点
function Person(name,age,eat,pao){
this.name = name;
this.age = age;
this.eat = eat;
this.pao = pao;
}
var zs = new Person('张三',12,function(){
console.log("会吃");
},function(){
console.log("能跑");
});
var ls = new Person('李四',13,function(){
console.log("会吃");
},function(){
console.log("能跑");
});
console.log(zs,ls);
构造函数的缺点:一模一样的函数在内存中会占用两个空间
优化2:
将函数定义在全局中,每个对象的方法都用这个函数赋值,可以解决构造函的缺点
var a = function(){
console.log("会吃");
}
var p = function(){
console.log("能跑");
}
function Person(name,age,eat,pao){
this.name = name;
this.age = age;
this.eat = eat;
this.pao = pao;
}
var zs = new Person('张三',12,a,p);
var ls = new Person('李四',13,a,p)
缺点:定义在全局中的函数或变量特别容易被覆盖
优化3:
创建对象使用自定义的构造函数,属性就在构造函数中添加
对象的方法,放在原型上。
function Person(name,age,eat){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){ //任何函数天生自带一个属性:prototype,这个东西是一个对象,原型/原型对象
console.log("会吃");
}
var zs = new Person("张三",12);
var ls = new Person("李四",13);
console.log(zs,ls);
zs.eat()
ls.eat()
重点:
任何函数天生自带一个属性:prototype,这个东西是一个对象,原型/原型对象
任何一个对象,天生自带一个属性:__proto__ , 这个东西是一个对象,原型/原型对象
当对象在调用一个方法时,首先看自己有没有,有就能调用,没有找他的原型要,原型有就能调用,没有,就找原型的原型要,一直往上找,找到就能调用,一直到了null也没有找到,调用会报错 ... is not a function
一个对象在访问一个属性的时候,首先看自己有没有,有就能访问,没有找他的原型要,原型有就用,没有,就找原型的原型要,一直往上找,找到就能用,一直到了null也没有找到,返回undefined
一个对象在访问一个属性的时候,首先看自己有没有,有就能访问,没有找他的原型要,原型有就用,没有,就找原型的原型要,一直往上找,找到就能用,一直到了null也没有找到,返回undefined