面向对象,就是给对象添加属性,通过对象的属性完成需求。
一个简单的例子,创建一个对象,并给对象添加属性。
var obj = new Object();
obj.name = 'tom';
obj.age = 18;
obj.showName = function(){
return this.name;
};
obj.showAge = function(){
return this.age;
};
一封装
进行函数封装,就变成了工厂模式
function person(name,age){
//原料
var obj = new Object();
//加工
obj.name = name;
obj.age = age;
obj.showName = function(){
return this.name;
};
obj.showAge = function(){
return this.age;
};
//出厂
return obj;
}
这种封装方法,比较简单,但缺点是每次调用函数的时候都会创建新的对象,因此对象里的属性都是独立的,实例之间没有内在联系。
构造函数和原型
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.showName = function(){
return this.name;
};
Person.prototype.showAge = function(){
return this.age;
};
Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承,这样所有实例用到的prototype上的属性,其实都是同一个内存地址,因此就提高了运行效率,并且把实例和原型联系了起来。
二继承
1、继承构造函数里的属性
function Animal(){
this.species = '动物';
}
function Dog(name,age){
Animal.apply(this,arguments);
this.name = name;
this.age = age;
}
2、继承原型的方法
function Animal(){}
Animal.prototype.species='动物';
function Cat(name,age){
this.name = name;
this.age = age;
};
a:
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
缺点:污染父级原型对象
b:
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
缺点:会带人父级构造函数中的属性,占用内存。
c:
for(var name in Animal.prototype){
Cat.prototype[name] = Animal.prototype[name];
}
Cat.prototype.constructor = Cat;
缺点:父级和子级关系断了。
d:
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
e:
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;