JS进阶3之(面向对象 封装 构造函数 原型对象 原型继承 原型链
一、面向对象
面向对象编程是一种程序设计思想,它具有 3 个显著的特征:封装、继承、多态。
1.1 封装
封装的本质是将具有关联的代码组合在一起,其优势是能够保证代码复用且易于维护,函数是最典型也是最基础的代码封装形式,面向对象思想中的封装仍以函数为基础,但提供了更高级的封装形式。
1.1.1 命名空间
以往以普通对象(命名空间)形式封装的代码只是单纯把一系列的变量或函数组合到一起,所有的数据变量都被用来共享(使用 this 访问)。
let beats = {
name: '狼',
setName: function (name) {
this.name = this.name;
},
getName() {
console.log(this.name);
}
}
beats.setName('熊');
1.1.2 构造函数
构造函数相当于一个模板 能够像字面量那样创建出对象来
所不同的是借助构造函数创建出来的实例对象之间互不影响
构造函数体现了面向对象的封装特性
构造函数实例创建的对象彼此独立、互不影响
命名空间式的封装无法保证数据的独立性
function Star(uname, age) {
this.uname = uname
this.age = age
this.sing = function () {
console.log('唱歌');
}
}
let ol1 = new Star('刘德华', 30);
let ol2 = new Star('周星驰', 28);
1.1.3 原型对象
每一个构造函数都由prototype(原型)属性
prototype称为构造函数的原型对象
每个原型对象都有constructor属性 代表改原型对象所对应的构造函数
function Person(uname, age) {
this.uname = uname
this.age = age
}
Person.prototype.sing = function () {
console.log('唱歌');
}
console.log(Person.prototype);
let obj = new Person('阿飞', 22);
console.log('obj', obj);
obj.sing()
当访问对象的属性或方法时,先在当前实例对象是查找,然后再去原型对象查找,并且原型对象被所有实例共享。
function Person(uname, age) {
this.uname = uname
this.age = age
this.sing = function () {
console.log('构造的sing方法');
}
}
Person.prototype.sing = function () {
console.log('原型对象');
}
console.log('构造函数', Person, Person.prototype);
let obj = new Person('唱歌', 24);
console.log('实例化对象', obj.sing);
每一个原型对象都有一个属性 constructor:用于指回构造函数本身
function fn() {
console.log('构造函数');
}
console.log(fn.prototype.constructor);
function Person(uname, age) {
this.uname = uname
this.age = age
}
let obj = new Person('阿飞', 22);
console.log('实例对象', obj.constructor);
每一个实例对象都有一个属性:__proto__(隐形原型) ===Person.prototype
function Person(uname, age) {
this.uname = uname
this.age = age
}
Person.prototype.sing = function () {
console.log('原型对象', Person);
}
let obj = new Person('阿飞', 22);
console.log('实例对象', obj.__proto__);
function Person(uname, age) {
this.uname = uname
this.age = age
}
Person.prototype.eatn = function () {
console.log('吃饭');
}
let obj = new Person();
console.log('实例化对象', obj);
1.2 继承
继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。
1.2.1 原型继承
function Chinese() {
this.skin = 'yellow';
this.language = '中文';
}
function Japanese() {
this.skin = 'yellow';
this.language = '日文';
}
let people = {
arms: 2,
legs: 2,
eyes:2,
walk: function () {},
sleep: function () {},
sing: function () {}
}
Chinese.prototype = people;
Chinese.prototype.constructor = Chinese;
防止继承时改变公共属性的值 使用公共构造函数的实例对象赋值给原型对象
function People() {
this.head = 1
this.eyes = 2
this.leg = 2
this.height = '100cm+'
this.eat = function () {
console.log('吃饭');
}
}
function Star() {
this.daban = '打扮'
this.money = '$$$'
}
function Player() {
this.suzhi = '好'
this.lihai = '天赋'
}
Star.prototype = new People
Star.prototype.constructor = Star
let ak = new Star()
console.log('ak', ak);
1.2,2 原型链
原型链:由原型构成的链状结构
作用:提供查找成员的机制
function Person(uname, age) {
this.uname = uname
this.age = age
}
Person.prototype.eat = function () {
console.log('吃');
}
let obj = new Person('阿飞', 22);
console.log(obj.__proto__);
console.log(Person.prototype.__proto__.constructor);