面向对象编程
一、面向对象的概念
ES有两种开发模式:
-
函数式 面向过程
-
面向对象(OOP)
类:类是对象的类型模板
实例:实例就是根据类创建的对象
对象的组成:
- 属性 特性、特征 名词 变量
- 方法 功能、行为 动词 函数
二、对象的创建
1.实例创建
//学生对象
var obj=new Object();
obj.no='10001';
obj.name='李四';
obj.grade='二年级';
obj.test=function(){
console.log('考试中........');
};
2.字面量形式创建
var obj = {};//实例
obj.name = '赵露思';
obj.show = function () {
console.log('哈哈哈,我是老赵');
};
var obj1 = {
name1: "李思思", //键值对
show: function () {
console.log('哈哈哈哈,我是老李');
}
};
3.工厂函数创建对象
//工厂函数
function createStudent(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.test = function () {
console.log('考试中');
};
return obj;
}
优点:可以批量的产生对象
缺点:代码相对复杂,会为每一个对象都新增方法 不能解决类型识别问题
4.构造函数
最常用的一种批量创建对象的方式
1)构造函数的特点:
- 函数名大写
- 构造函数需要通过new关键字来调用
- 构造函数没有return语句
2)分析构造函数的执行流程:
- 当使用new关键字来调用构造函数时,系统会创建一个对象实例(new Object())
- 将this指向创建的对象实例
- 为对象实例添加属性和方法
- 将构造完毕的对象返回给调用者
优点:能够批量创建对象,解决对象识别问题
缺点:内存浪费
5.原型创建对象
1)原型
所有对象都有一个原型属性,该属性是对象,原型对象。
放入原型中的属性和方法对该对象实例来说,都是公有的。
2)proto
是对象实例的属性
__proto__
console.log(s.__proto__==Student.prototype);//true
/*
每一个对象实例都有一个属性 __proto__属性,该属性执行原型对象
也就是说__proto__和Student的prototype是同一个东西
*/
3)constructor
原型对象的constructor属性指向构造函数
console.log(Student.prototype.constructor==Student);//true
通过原型的方式创建对象
function Student() { }
Student.prototype.name = "李四";
Student.prototype.say = function () {
console.log(this.name + "说话中....");
};
缺点:无法解决传参问题(个性化)
6.混合模式创建对象
构造函数+原型
在构造函数中完成属性的添加,在原型中完成方法的添加。
是一种较为理想的创建对象的模式
//学生
function Student(name, no, age) {
this.no = no;
this.name = name;
this.age = age;
}
//原型中添加方法
Student.prototype.test = function () {
console.log(this.name + " 考试中。。。。。。。。");
};
7.动态混合模式
混合模式创建对象,将对象声明分为了两部分(构造函数和原型),视觉上有一定的"割离感"。
所以,可以将在原型中添加方法的代码放入构造函数,
//人 对象
function Person(name, age, addr) {
this.name = name;
this.age = age;
this.addr = addr;
if (!this.say) {//若say方法没有被添加过,则添加
Person.prototype.say = function () {
console.log(this.name + "说话中....");
};
}
// Person.prototype.walk = function () {
// console.log(this.name + " 走路....");
// };
}
三、面向对象编程实例
打飞机
四、补充知识点:
1.命名空间
var obj = {};
obj.name = 10;
obj.age = 20;
obj.offcn = {};//命名空间
obj.offcn.name = 'hello';
obj.offcn.age = 'world';
console.log(obj.name);
console.log(obj.offcn.name);
2.call和apply
this在不同的地方指向不一样
call和apply能够改变this的指向
call和apply是所有函数对象都有的方法
fn.call(对象,参数1,参数2,...)
fn.apply(对象,[参数,参数,...])
相同点:都可以更改函数内this指向
不同点:参数传递形式不一样
五、继承
父类:
子类:
继承是单向的。 单继承
面向对象三大特征:继承、多态、封装
继承:子类继承父类属性和方法
1.原型链继承
将父类的实例化赋值子类的原型。
function Person() {
this.name = "李四";
}
Person.prototype.say = function () {
console.log('我跑呀跑呀跑');
};
function Student() {
this.no = '1000';
}
//实现继承,原型链继承
Student.prototype = new Person();
var s = new Student();
console.log(s.no);
console.log(s.name);
s.say();
通过继承会继承父类所有的属性和方法,通过继承的操作,各个对象之间建立了联系,形成了链条,实例对象在获取属性和方法的时候,可以根据链条往上寻找,因此称为原型链继承。查找的顺序,自己实例对象-构造函数-原型-父类型的实例对象-父类型构造函数-父类型原型-…。