一、构造函数补充
我们知道,ES6创建类是使用关键字class
// ES6创建类
class Bull{
constructor(weight,color){
this.weight = weight;
this.color = color;
this.descri();
}
descri(){
console.log('这只球有'+this.weight+'kg,'+'是个'+this.color);
this.shou();
}
shou(){
console.log('我很喜欢它');
}
}
var b1 = new Bull(10,'红色');//这只球有10kg,是个红色 我很喜欢它
那ES6之前通常是怎样创建类的呢?
答:是通过构造函数+prototype的方式
// ES5创建类
function Bull(weight,color){
this.weight = weight;
this.color = color;
}
// 通过prototype添加方法
// 如果利用对象的形式修改了原型对象,
// 需要constructor指回原来的 构造函数
Bull.prototype = {
//指回原来的构造函数
constructor:Bull,
descri:function(){
console.log('这只球有'+this.weight+'kg,'+'是个'+this.color);
},
shou:function(){
console.log('我很喜欢它');
}
}
var b2 = new Bull(20,'蓝色');
b2.descri(); //这只球有20kg,是个蓝色
b2.shou(); // 我很喜欢它
console.log(b2);
没加之前的:
加了之后的:
ES5类案例:随机100个小球
function Box() {
this.width = parseInt(Math.random() * 100);
this.r = parseInt(Math.random() * 256);
this.g = parseInt(Math.random() * 256);
this.b = parseInt(Math.random() * 256);
this.top = parseInt(Math.random() * 700);
this.left = parseInt(Math.random() * 1100);
this.radius = "50%";
}
Box.prototype = {
constructor:Box,
createCircle: function () {
var div = document.createElement("div");
div.style.position = "absolute";
div.style.width = this.width + "px";
div.style.height = this.width + "px";
div.style.backgroundColor = "rgb(" + this.r + "," + this.g + "," + this.b + ")";
div.style.top = this.top + "px";
div.style.left = this.left + "px";
div.style.borderRadius = this.radius;
document.body.appendChild(div)
}
}
//循环创建100个小球
for (var i = 0; i < 100; i++) {
var oCircle = new Box();
oCircle.createCircle();
}
效果图:
二、设计模式
2.1、概念
什么是设计模式?
设计模式(Design pattern)是一套被反复使用、思想成熟、经过分类和无数实战设计总结的经验。
为什么要学设计模式?
使用设计模式是为了让系统代码可重用、可扩展、可解耦、更容易被人理解且能保证代码可靠性。是我们迈向高级开发人员必经的一步。
设计模式是一种思想,一种思路。
2.2、设计模式的分类
种类较多,通常认为是有23种设计模式,分为以下几大类
-
创建型:
1. 抽象工厂模式 2. 工厂方法模式 * 3. 建造者模式 4. 原型模式 5. 单例模式(又称单体模式)*
-
结构型:
1. 适配器模式 2. 桥接模式 3. 组合模式 * 4. 装饰者模式 5. 外观模式 6. 享元模式 7. 代理模式 *
-
行为型:
1. 职责链模式 2. 命令模式 3. 解释器模式 4. 迭代器模式 5. 中介者模式 6. 备忘录模式 7. 观察者模式(又称发布/订阅模式)* 8. 状态模式 9. 策略模式 10. 访问者模式 11. 模板方法模式
2.3、单例模式
我们先学习下单例模式
简单来说,单例模式就是指一个类只能有一个实例对象。
在日常生活中,注册账号就是一个单例设计模式,假如该账号已经存在,就无法再创建一个一模一样的账号了。
- 单例设计模式的实现思路
普通类
//普通类
class Bull {
constructor(name){
this.name = name;
}
}
var b1 = new Bull('小明');
var b2 = new Bull('小丽');
console.log(b1===b2);//false 说明可以实例化很多个对象,不属于单例模式
简单的单例模式实现
//简单的单例模式实现
class Big{};
var fla; //默认还没有实例化过类
function Do(name){
if(!fla){
//没有实例化过类
//初始fla为undefined ,即false
fla = new Big();
}
//实例化过类,直接结束函数
return fla;
}
var d1 = new Do();
var d2 = new Do();
// 因为只实例化一次类,所以属于单例模式
console.log(d1===d2);//true
单例模式(闭包实现)
// 单例模式(闭包实现) 目的:降低全局污染
var se = (function(){
class Color{};
var chu;
return function(){
if(!chu){
chu = new Color();
}
return chu;
}
})()//立即调用函数 IIFE
var s1 = se();
var s2 = se();
// 同样只实例化了一次类,故相等
console.log(s1===s2);//true
2.4、组合模式
就是用小的子对象来构建更大的对象,包含了叶对象和叶对象组合而成的组合对象。
// 简单的组合模式实现
class Tab{
init(){
console.log('tab');
}
}
class Banner{
init(){
console.log('banner');
}
}
class Top{
init(){
console.log('top');
}
}
class Compose{
constructor(){
this.events = [];//初始化数组,用于存储每一个小对象
}
add(obj){
this.events.push(obj);// 将小的对象存储到数组中
}
execute(){
//循环调用init方法
for(var i=0;i<this.events.length;i++){
this.events[i].init();//调用每一个小对象的init方法
}
}
}
var c= new Compose();
c.add(new Tab())
c.add(new Banner())
c.add(new Top())
c.execute();
2.5、代理模式
就是把对一个对象的访问,交给另一个代理对象来操作。
// 简单的代理模式实现
class Boss{
constructor(zhuli){
this.name = zhuli; // zhuli----> new Zhuli(‘小李’)
}
buyTea(){
this.name.buyTea()
}
buyCoffee(){
this.name.buyCoffee()
}
buySmoke(){
this.name.buySmoke()
}
}
class Zhuli{
constructor(name){
this.name = name;
}
buyTea(){
console.log(this.name+'买碧螺春茶叶');
}
buyCoffee(){
console.log(this.name+'买咖啡');
}
buySmoke(){
console.log(this.name+'买烟');
}
}
var b = new Boss(new Zhuli('小李'))
b.buyCoffee()
b.buyTea();
b.buySmoke();
2.6、工厂模式
就是用工厂的思路创建对象,这些对象一般具有共同的父类。
// 简单的工厂模式实现
function factory(params) {
function Shui() {
this.name = '水'
}
function Ru() {
this.name = '乳'
}
function Shuang() {
this.name = '霜'
}
switch (params) {
case 'shui':
return new Shui();
break;
case 'ru':
return new Ru();
break;
case 'shuang':
return new Shuang();
break;
default:
break;
}
}
console.log(factory('shui'));
console.log(factory('ru'));
console.log(factory('shuang'));
2.7、观察者模式
定义了多个观察者对象,一个主对象,主对象发生改变,观察者对象随之做出改变。
// 简单的观察者模式实现
var student1 = {
waiting:function(msg){
console.log('student1接收到了'+msg);
}
}
var student2 = {
waiting:function(msg){
console.log('student2接收到了'+msg);
}
}
var student3 = {
waiting:function(msg){
console.log('student3接收到了'+msg);
}
}
var student4 = {
waiting:function(msg){
console.log('student4接收到了'+msg);
}
}
// 被观察者 发布者
class Ling{
constructor(params){
this.student = params;// 传进去的是一个数组
}
sendMsg(what){
for(var i =0;i<this.student.length;i++){
this.student[i].waiting(what); // 将消息传出到每一个学生那里
}
}
}
var l = new Ling([student1,student2,student3,student4])
经典案例: localStorage实现购物车
//点击加入购物车,存入本地localStorage
//打开页面即读取
var resu;
var count = 1;
var flag;
window.onload = function () {
//若读取到数据,说明之前存储过
//若为[],证明之前没有存储过
resu = getLocal('shop');
// console.log(resu);
}
for (let i = 0; i < oBut.length; i++) {
//给每个按钮一个自定义属性
oBut[i].index = i;
oBut[i].onclick = function () {
//获取点击的按钮所在的li中关于商品的相关信息
var src = this.parentElement.children[0].src;
var context = this.previousElementSibling.innerHTML;
var price = this.parentElement.children[1].children[0].innerHTML;
for (var i = 0; i < resu.length; i++) {
//同一个按钮点击多次,改变count的值
if (this.index == resu[i].id) {
//说明同个商品点击了多次
resu[i].src = src;
resu[i].context = context;
resu[i].price = price;
resu[i].count++;
flag = true;
break;
} else {
flag = false;
}
}
if (!flag) {
//flag为false时执行以下代码
//往存储值的数组中添加json数据
resu.push({ 'id': this.index, 'src': src, 'context': context, 'price': price, 'count': count });
// console.log(oBut[i].index);
}
//存储数据到localStorage
setLocal('shop', resu);
//等待5s,跳转到购物车页面
setTimeout(function () {
location.href = 'shop.html';
}, 5000)
}
}
添加购物车页面
购物车详情页面
页面功能还在完善中…