六:以理论结合实践方式梳理前端 ES 6+ ——— ES 6+ 面向对象

ES 6+ 面向对象

面向对象是一种通用思想,并非只有编程中能使用,任何事务都可以使用

  • 唯一性:每个对象读有自身的唯一标识,通过这种标识,可以找到对应的对象
  • 抽象性:就是指将具有一致的数据结果(属性)和行为(操作)的对象规程一类
  • 继承性:是一种子类自动共享父类的数据结构和方法的机制,也是类之间的一种关系
  • 多态性:是指作用在不同的对象中,使用相同的操作,却产生不同的结果

面向对象三大特性:抽象、封装、继承

var obj = { name: 'tom', age: 5 };
obj.say = function() {
	console.log('miao! my name is ' + this.name + ', I\'m ' + this.age);
};
obj.say();					// "miao! my name is tom, I'm 5"

对象模板

JavaScript 是一种基于对象的语言,但它不是一种真正的面向对象编程语言,因为 JavaScript 中没有类,只能抽象生成类的创建,ES 6 以后就有类的概念

  • 构造函数法:通过声明函数定义一个类,并使用 this 指向对象的属性和方法,通过构造函数引入这个类
  • 创建对象法:通过声明对象定义一个类,并在对象中设置对象的属性和方法,通过 Object.create() 生成一个实例
  • 极简主义法(推荐):通过声明对象定义一个类,并在对象中设置一个构造函数,用于生成实例,直接调用构造函数生成一个实例
function Cat() {
	this.disc = '猫';
	this.sound = function() {
		return '喵!!!';
	}
}
var tom = new Cat();
console.log('tom 是一只' + tom.disc + '它只会说:' + tom.sound());					// 'tom 是一只猫它只会说:喵!!!'
--------------------------------------------------------------------------------------------------------------------------------
var Cat = {
	disc: '猫',
	sound: function() {
		return '喵!!!';
	}
};
var jerry = Object.create(Cat);
console.log('jerry 是一只' + jerry.disc + '? 它会说:' + jerry.sound() + '?');		// "jerry 是一只猫? 它会说:喵!!!?"
--------------------------------------------------------------------------------------------------------------------------------
var Cat = {
	newCat: function() {
		var cat = {};
		cat.disc = '猫';
		cat.sound = function() {
            return '喵!!!';
        };
        return cat;
	}
};
var terry = Cat.newCat();
console.log('terry 是一只' + terry.disc + '它只会说:' + terry.sound());			// 'tom 是一只猫它只会说:喵!!!'

封装特性

封装就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的类或者对象进行信息隐藏

  • 生成实例对象的原始模式:把对象的属性和方法看成是封装在对象内部的,外部需要通过对象才能进行属性和方法的访问
  • 生成构造函数的改进模式:通过构造函数传值赋值给构造函数,外部表用需要通过实例化构造函数进行属性和方法的访问
    • 声明的构造函数就是类,通过 new 构造函数产生实例是实例对象
    • 构造函数中的 this 指向的是构造函数这个类,使用构造函数创建类建议函数名首字母大写
var Cat = {
	name: '',
	color: ''
};
Cat.name; Cat.name = 'tom';
--------------------------------------------------------------------------------------------------------------------------------
function Cat(name, color) {
	this.name = name;
	this.color = color;
}
var tom = new Cat('tom', 'blue');
tom.name; tom.color;
--------------------------------------------------------------------------------------------------------------------------------
function Cat(name, color) {
	this.name = name;
	this.color = color;
	this.type = '猫科动物';
}
var tom = new Cat('tom', 'blue');	// 每次实例会造成内存浪费问题,可以通过原型机制改变引用类型地址指向

原型机制

每个构造函数都具有一个 prototype 属性,用于指向对象添加属性和方法,一般情况下属性放在构造函数内,方法通过原型生成,且可以共享出去,构造函数还有一个 __protp__ 原型链,用于指向实例化的函数原型

function Person(name, sex, age) {
	this.name = name;
	this.sex = sex;
	this.age = age;
}
Person.prototype.say = function() {
	console.log('hi');
};
var tom = new Person('tom', 'boy', 12);
var lily = new Person('lily', 'girl', 10);
tom.say();				// "hi"
lily.say();				// "hi"
--------------------------------------------------------------------------------------------------------------------------------
var Person = {
	newPerson: function(name, age) {
		var cat = {};
		cat.name = name;
		cat.age = age;
        return cat;
	}
};
var tom = Person.newPerson('tom', 12);
tom.say = function() {
	console.log('My name is ' + this.name + ', i\'m ' + this.age);
};
tom.say();				// ”My name is tom, i'm 12“
--------------------------------------------------------------------------------------------------------------------------------
tom.__proto__ === Person.prototype;			// true

原型验证

验证方法方法说明
isPrototypeOf()用来判断某个 prototype 对象和某个实例之间的关系
hasOwnProperty()用来判断某一个属性到底是本地属性还是继承自 prototype 对象的属性
in 运算符用来判断某个属性是否是对象的属性,不管是不是本地属性或 prototype 对象的属性
function Cat(name, color) {
	this.name = name;
	this.color = color;
}
Cat.prototype.type = '猫科动物';
var tom = new Cat('tom', 'blue');
Cat.prototype.isPrototypeOf(tom);			// true
tom.hasOwnProperty('name');					// true
tom.hasOwnProperty('type');					// false
('name' in tom);							// true
('type' in tom);							// true
/**
 * 对 Date 的扩展,将 Date 转化为指定格式的 String 日期格式
 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
 * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符
 * @param  {[Date]} this [需要转化格式的日期时间]
 * @param  {[String]} fmt  [转化格式]
 * @return {[String]}      [返回转化后的格式化日期字符]
 * new Date().format('yyyy-MM-dd hh:mm:ss.S') ==> 2020-07-22 21:54:08.58
 * new Date().format('yyyy-M-d h:m:s.S') ==> 2020-7-22 21:54:8.58
 */
Date.prototype.format = function(fmt) {
	var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) {
    	fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    for (var k in o) {
    	if (new RegExp("(" + k + ")").test(fmt)) {
    		fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    	}
    }
    return fmt;
};
--------------------------------------------------------------------------------------------------------------------------------
/**
 * 对 Date 的扩展,通过传递一个日期时间,根据调整模式判断调整对应模式的日期时间
 * @param  {[Date]} this  [传递过来的参考日期时间]
 * @param  {[String]} mode  [传过来的调整模式:M 月、d 天、h 时、m 分、s 秒]
 * @param  {[Number]} value [正数: 当前时间后时间,负数: 当前时间前时间]
 * @return {[Date]}       [返回处理后的日期时间]
 * 得到当前系统时间 var now = new Date(); ==> Wed Jul 22 2020 22:10:30 GMT+0800 (中国标准时间)
 * new Date().interval('d', -1); ==> Tue Jul 21 2020 22:10:25 GMT+0800 (中国标准时间)
 */
Date.prototype.interval = function (mode, value) {
	switch(mode) {
		case 'M': this.setMonth(this.getMonth() + value); break;
		case 'd': this.setDate(this.getDate() + value); break;
		case 'h': this.setHours(this.getHours() + value); break;
		case 'm': this.setMinutes(this.getMinutes() + value); break;
		case 's': this.setSeconds(this.getSeconds() + value); break;
	}
	return this;
};

继承特性

通过继承创建的新类称为”子类“或”派生类“,继承的整个过程就是从一般到特殊的过程。

function Person(name, age) {
	this.name = name;
	this.age = age;
}
Person.prototype.say = function() {
	console.log('My name is ' + this.name + ', i\'m ' + this.age);
}
function Man() {
	this.sex = 'boy';
}
Man.prototype = Person.prototype;						// 继承人的特征或属性
var tom = new Man();
tom.name = 'tom';
tom.age = 12;
tom.say();												// "My name is tom, i'm 12"
--------------------------------------------------------------------------------------------------------------------------------
var Animal = {
	newAnimal: function() {
		var animal = {};
		animal.call = function(val) {
			return '只会说: ' + val;
		};
		return animal;
	}
};
var Cat = {
	newCat: function() {
		var cat = Animal.newAnimal();
		cat.disc = '猫';
        return cat;
	}
};
var tom = Cat.newCat();
console.log('tom 是只' + tom.disc + tom.call('喵~'));		// "tom 是只猫只会说: 喵~"
--------------------------------------------------------------------------------------------------------------------------------
function Person(name, age) {
	this.name = name;
	this.age = age;
}
Person.prototype.say = function() {
	console.log('My name is ' + this.name + ', i\'m ' + this.age);
}
function Man(name, age) {
	var man = new Person(name, age);
	man.sex = 'boy';
	return man;
}
var tom = new Man('tom', 12);
tom.say();												// ”My name is tom, i'm 12“

多态特性

对象的多功能、多方法,一个方法呈现多种表现形式,以下解析:同样是动物类,猫是喵叫,狗是汪汪叫

var Animal = {
	newAnimal: function() {
		var animal = {};
		animal.call = function(_type) {
			return '只会说: ' + (_type === 'cat' ? '喵~' : '汪汪~');
		};
		return animal;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值