JS面向对象编程(OOP)
面向对象编程 OOP
1 面向对象 & 面向过程
面向过程 POP
分析问题所需要的步骤
面向对象OOP
以功能对象划分问题
二者比较:
面向对象 | 面向过程 | |
---|---|---|
优 | 灵活 复用 维护 | 性能高 |
缺 | 性能比面向过程低 | 没有面向对象灵活、复用、维护 |
2 类和对象
笔记本 泛指 类
mac笔记本 具体 实例
动物 猫
2.1 面向对象思维特点 :
- 抽取对象共用的属性和行为组织成一个类
- 对类进行实例化
2.2 对象
属性:事物的特征 名词
方法:事物的行为 动词
2.2.1 创建对象
// 对象直接量
var zs = {
name: 'zhangsan',
age: 18
};
// new Object() 通过构造函数创建 new Array()
var obj = new Object();
console.log(obj);
// 自定义构造函数
function Cat() {
this.color = 'black';
}
var c1 = new Cat(); // 类的实例 根据类创建一个具体对象
3 构造函数与原型
构造函数是一种特殊的函数,主要用来创建对象,总是与new一起
使用(通过new调用)
3.1 new 构造函数
- 在内存中创建一个新的空对象 {}
- 让函数中的this指向空对象 this === {}
- 开始执行函数体 {age: 22, xueli: ‘benke’}
返回该对象 (构造函数中不需要写return)
function Girl() {
console.log(this);
this.age = 22;
this.xueli = 'benke';
}
var girl1 = new Girl(); // {age: 22, xueli: ‘benke’}
var girl2 = new Girl();
console.log(girl1);
console.log(girl1 === girl2); // false
3.2 构造函数说明
构造函数添加:
1 构造函数内部this添加——实例成员 访问实例成员 对象.成员
2 在构造函数本身添加的成员——静态成员 只能通过构造函数去访问 一般用于创建公共属性
function Student(name, age) {
// name,age叫对象的属性(成员)
this.name = name;
this.age = age;
// study叫对象的方法 (成员)
this.study = function() {
console.log('day day up');
}
}
Student.nation = 'china'; // nation 静态成员 在构造函数本身添加的成员 一般用于定义公共属性
// 创建学生
var zs = new Student('zs', 22); // {name: 'zs', age: 22, study: ...}
var lisi = new Student('lisi', 19);
// 构造函数内部通过this添加的成员 叫实例成员 访问实例成员 对象.成员
console.log(zs.name);
zs.study();
// 访问静态成员 只能通过构造函数去访问
console.log(Student.nation);
console.log(Student.age); // 实例成员不能通过构造函数访问
3.3 原型
3.3.1 原型定义的函数是可共享(将来构造函数的实例都可以共享)
每一个构造函数都有一个prototype属性,指向一个对象,假如该对象定义了属性和方法 这些都会被构造函数拥有。
function Student(name, age) {
// name,age叫对象的属性(成员)
this.name = name;
this.age = age;
/* study叫对象的方法 (成员) this.study = function() { console.log('day day up'); } */
}
// 创建学生
var zs = new Student('zs', 22);
var lisi = new Student('lisi', 19);
/* console.log(zs.study === lisi.study); // false */
//构造函数原型对象
Student.prototype.run = function() {
console.log('running');
}
Student.prototype.study = function() {
console.log('day day up');
}
console.dir(Student.prototype);
zs.run();
lisi.run();
console.log(zs.study === lisi.study); //true
console.log(zs.run === lisi.run); //true
3.3.2 对象属性( __ proto __)
对象都会有一个属性__ proto __(非标准属性,开发不要使用),指向构造函数的prototype原型对象。
function Student(name, age) {
// name,age叫对象的属性(成员)
this.name = name;
this.age = age;
}
// 创建学生
var zs = new Student('zs', 22); //
var lisi = new Student('lisi', 19); //
Student.prototype.run = function() {
console.log('running');
}
Student.prototype.study = function() {
console.log('day day up');
}
zs.run();
// true
console.dir(zs.__proto__ === Student.prototype); // true
console.dir(lisi.__proto__ === Student.prototype); // true
console.log(zs.__proto__ === lisi.__proto__); // true
图解:
3.3.3 构造函数原型prototype属性 constructor
构造函数原型prototype属性 constructor,它的值指向构造函数。
Student —————-> Student.prototype
Student < —————- Student.prototype.constructor
// 构造函数
function Student(name, age) {
this.name = name;
this.age = age;
}
/* Student.prototype.study = function() { console.log('good good study'); } Student.prototype.run = function() { console.log('running'); } */
Student.prototype = {
constructor: Student, // 千万别忘记,不然会被重新赋值,丢失此属性
study: function() {
console.log('good good study');
},
run: function() {
console.log('running');
}
}
var zs = new Student('zs', 18); // 实例对象
var lisi = new Student('lisi', 22);
zs.study();
zs.run();
console.log(Student.prototype);
/* 原型对象 对象原型 console.log(Student.prototype === zs.__proto__); console.log(Student.prototype.constructor); console.log(zs.constructor === Student); console.log(zs.constructor === zs.__proto__.constructor); console.log(zs.constructor === Student.prototype.constructor); */
3.3.4 原型链
JS成员查找机制-原型链查找机制:
当我们访问一个对象的成员(方法或属性) 首先看自己有没有 ,假如没有就查找它的原型(也就是它的__ proto __),假如还没有,查找原型对象的原型(Object的原型对象),依次类推最终,找到Object。
图解:
推荐
在最后也推荐几篇我认为写得非常好的关于面向对象的文章:
- Javascript 面向对象编程(一):封装
- Javascript面向对象编程(二):构造函数的继承
- Javascript面向对象编程(三):非构造函数的继承
还没有评论,来说两句吧...