什么是面向对象编程: 使用对象的思想去写代码,就是面向对象编程。
特点:
- 抽象:抓住核心问题点。
- 封装:只能通过对象来访问。
- 继承:从已有对象上继承出新的对象。
- 多态:多对象的不同形态属性。
对象的组成:
属性:对象下面的变量叫做属性。
方法:对象下面的函数叫做方法。
var arr = [];
arr.number = 20; //对象下面的变量叫做属性。
arr.text = function(){
alert(123)
} //对象下面的函数叫做方法。
创建一个对象:
var obj = new Object(); //创建一个空的对象。
obj.name = '小黑!'; // 属性
obj.sayName = function(){
alert(this.name); //this指向obj
} //方法
obj.sayName() //小黑!
创建多个对象:
var obj1 = new Object();
obj1.name = '小明'
obj1.sayName = function(){
alert(this.name);
}
var obj2 = new Objcet();
obj2.name = '小红!'
obj2.sayName = function(){
alert(this.name);
}
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。
工厂方式:
面向对象中的封装函数:
function createPerson(name){
var obj = new Object();
obj.name = name;
obj.sayName = function(){
alert(this.name); //this指向obj
}
return obj;
}
var P1 = createPerson('小明!');
P1.sayName();
var P2 = createPerson('小红!');
P2.sayName();
创建对象使用工厂方式来实现,可以传递参数,由于创建对象都是使用Object的原生构造函数来实现的,因此无法识别对象类型。
构造函数模式:
EcmaScript中的构造函数可以用来创建特定类型的对象。像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象的类型和方法。
function Person(name) {
this.name = name;
this.sayName = function(){
alert(this.name); //this指向Person
}
}
var p1 = new Person('小红');
p1.sayName() // 小红
var p2 = new Person('小明');
p2.sayName() //小明
和工厂方式的区别:
1.没有在函数体内创建对象。
2.直接将属性方法给累this对象。
3.没有return语句。
创建一个Person新实例,必须用到new操作符。以这种方式调用构造函数实际上会经历一下4个步骤:
- 创建一个新的对象
- 将构造函数的作用域赋给新对象(因此this指向了这个新的对象)。
- 执行构造函数中的代码(为这个对象添加属性)。
- 返回新对象。
构造函数的问题:
每个方法都要在每个实例上重新创建一遍,在前面例子中,p1和p2都有一个名为sayName()的方法,但那两个方法不是同一个Function的实例,因为在ECMAScript中的函数是对象,因此,每创建一个函数,也就是实例化了一个对象。
console.log(p1.sayName == p2.sayName) //false
原型模式:
我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。按照字面意思来理解,prototype就是通过调用构造函数而创建的那个对象实例的原型对象。
function Person = function(){
}
Person.prototype.name = '小红';
Person.prototype.sayName = function(){
alert(this.name);
}
var p1 = new Person();
p1.sayName() // 小红
var p2 = new Person();
p1.sayName() // 小红
console.log(p1.sayName == p2.sayName) //true
理解原型对象:无论什么时候,只要创建了一个新函数之后,就会根据一组特定的规则为该函数创建一个prorotype属性,这个属性指向函数的原型对象。在默认情况下所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针。