什么是面向对象?
简单来说就是在程序中用对象结构来描述现实中的一个具体事物。
什么是对象?
程序中描述现实中一个事物的属性和功能的程序性结构。
面向对象的三大特点
封装:创建一个对象,集中储存一个事物的属性和功能。
继承:父对象中的成员,子对象无需重复创建可直接使用。
多态:同一事物,在不同情况下,表现出不同的状态。
封装:
将一个事物的属性和功能集中在一个对象中。
事物的属性会成为对象的属性,其实就是保存在对象中的普通变量。
事物的功能会成为对象的方法,其实就是保存在对象中的普通函数。
对象的成员,属性和方法统称为成员。
只要使用面向对象,都要先创建对象,再按需调用对象的方法执行操作。
有三种方式可以创建
对象直接量创建:
//对象直接量创建
var obj = {
name:'李四',
age:22,
method:function(){
console.log('年龄:'+this.age);
}
}
console.log('姓名:'+obj.name);
obj.method();
注意事项:访问对象内部的方法,如果不加this,仅会在作用域链中查找,不会再对象中查找。
解决办法:this.属性名,如this.age。只要对象自己的方法访问自己的属性,必须用this.属性名。
用new创建
//new创建
var obj = new Object(); //创建一个新的空对象。
obj.name = '李四'; //为新对象添加新属性
obj['gender'] = '男'; //为新对象添加新属性
var email = '';
obj[email] = '123@qq.com';
obj.age = 22;
obj.method = function(){//为新对象添加新方法
console.log('姓名:'+this.name);
}
obj.method();
console.log('年龄:'+obj.age);
console.log('性别:'+obj.gender);
console.log('邮箱:'+obj[email]);
提示:obj.属性名,等效于obj['属性名'],但当访问属性名是变量时只能用[变量]。
用构造函数创建
//用构造函数创建
function Func(name,age){ //定义构造函数
this.name = name;
this.age = age;
this.method = function(){ //js中不推荐将方法定义在构造函数中
console.log('姓名:'+this.name);
}
}
//用new调用构造函数
var obj = new Func('张三',22); //实例化一个对象
obj.method();
console.log('年龄:'+obj.age);
问题:无法节约内存:放在构造函数中的方法定义,每new一次,都会创建函数对象副本。
解决:使用继承。
new
1.创建了一个新对象
2.设置新对象的__proto__继承构造函数中的prototype对象
3.调用构造函数,将构造函数中的this.自动替换为当前对象
4.返回新对象的地址保存到变量中
this
是指自动引用正在调用当前方法的对象。
不用this的普通变量,只能在作用域链中查找,无法进入到对象中。
一般对象的变量名不可能写死在对象的方法内部所以用this代替。
只要希望去当前对象中找属性时,就必须用this.属性名。
如:
obj.fun() //fun中的this指向obj
new Fun() Fun中的this指向正在创建的新对象
类型.prototype.fun //fun中的this指向将来调用fun的子对象,子对象一定是当前类型
提示:如果this不是想要的可以使用ES5中的call替换。 fun.call(替换this的对象)
继承:
指父对象中的成员,子对象无需重复创建即可直接使用。
只要多个子对象拥有共同的属性值或者方法时,仅需集中定义在父对象中一份,所有子对象共用即可。
JavaScript中的继承都是继承原型对象也就是原型继承。
原型对象
指集中保存同一类的所有子对象共有成员的父对象。
只要有多个子对象拥有相同的成员时,都要将相同的成员集中保存在原型对象中一份即可。
如何创建?
不用创建,在创建构造函数时,已经自动创建了该类型的原型对象。
构造函数.prototype指向原型对象
原型对象.constructor指回构造函数
//原型对象继承
var father = {bal:10000000000, car:"infiniti"};
function Func(name,age){
this.name = name;
this.age = age;
}
Func.prototype = father;
Func.prototype.intr = function(){
console.log('名字:'+this.name,'年龄'+this.age);
}
var lisi = new Func('李四',22);
console.log('李四的存款:'+lisi.bal,'李四的车'+lisi.car);
lisi.intr();
new 每新创一个子对象,都会自动设置子对象的__proto__继承构造函数的原型对象
向原型对象中添加共有成员:构造函数.prototype.成员=值或方法。
多态
一个引用类型(变量),在不同情况下表现出不同的状态。
重载(overload)
重写(override)如果子对象觉得父对象成员不好用,可以本地定义同名自有成员,来覆盖父对象中的成员。