设计模式-cookie


typora-root-url: images
typora-copy-images-to: images

单例模式

什么是单例模式
 单例模式也称作为单子模式,单体模式。单例模式的定义是产生一个类的唯一实例,是软件设计中较为简单但是很常用的一种设计模式。

单例模式的核心是确保只有一个类一个实例,并提供全局访问.

单例的使用

核心思想

无非是用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象

多次实例化,返回一个对象

    function fn(){
        console.log(1111);
        if(!fn.obj){
            fn.obj={
                name:'cheng'
            }
        }
        return fn.obj;
    }
     var obj1 = new fn();
     var obj2 = new fn();
    console.log(obj1==obj2);

分析:

  这是一个最经典的惰性单例,如果实例不存在,通过一个方法创建一个实例,如果已经存在,则返回实例的引用。这里就说明了它和静态对象不同,可以被延迟生成,也就是说在我们需要的时候才创建对象实例,而非在页面加载时就创建。

ES6中的实现

    class A{
       obj = '';
        say(){
            console.log('哈哈');
        }
         static getObj(){
             if(!this.obj){
                 this.obj = new A;
             }
             return this.obj;
         }
    }
    let a1 = A.getObj();
    let a2 = A.getObj();
    console.log(a2);
    console.log(a1===a2);
单例模式实现弹出框(了解)

不管点击多少次,只会实例化一次

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    /*
      自定义弹出层
        + 从 html 到 css 到 js 效果全部由 Dialog 类实现
    */

    // 需要弹出层的时候
    // success  成功  绿色
    // warning  警告  橘黄色
    // danger   危险  红色
    // info     信息  蓝色
    // default  默认  白色
    const Dialog = (function () {
  // 专门准备一个设置 css 样式的方法
  // ele 表示给哪一个元素设置
  // styles 表示设置哪些样式 { left: '100px', right: '200px' }
  function setStyle(ele, styles) {
    for (let k in styles) {
      ele.style[k] = styles[k]
    }
  }

  // 照常书写构造函数
  class Dialog {
    constructor () {
      // 创建一个 div
      this.ele = document.createElement('div')
      // 准备一个备选的数组
      this.status = [
        { color: '#fff', text: '', type: 'default' },
        { color: 'orange', text: '警告', type: 'warning' },
        { color: 'green', text: '成功', type: 'success' },
        { color: 'red', text: '错误', type: 'danger' },
        { color: 'skyblue', text: '信息', type: 'info' }
      ]

      this.init()
    }

    // 准备 init 函数
    init () {
      // 设置 div 内部的结构
      this.setDivInnerHtml()
      // 设置 div 内部的样式
      this.setDivInnerStyle()
      // 设置 div 内的事件
      this.setEvent()
      // 把 div 插入到页面
      document.body.appendChild(this.ele)
    }

    // 准备 change 函数
    change (type, msg) {
      // 调整 top 和 bottom 的颜色
      // 1. 确定颜色
      const status = this.status.find(item => item.type === type) || { color: '#fff', text: '', type: 'default' }

      // 2. 调整颜色
      this.setColors(status)

      // 3. 修改文本
      this.setText(msg)

      // 4. 让 this.ele 显示出来
      this.ele.style.display = 'flex'
    }

    // 需要一个方法, 确定 div 内的 html 结构
    setDivInnerHtml () {
      this.ele.innerHTML = `
        <div class="top">
          错误
        </div>
        <div class="center">
          注册失败, 该用户名已经被占用
        </div>
        <div class="bottom">
          <button>关闭</button>
        </div>
      `
    }

    // 需要一个方法, 设置 div 及内部所有标签的样式
    setDivInnerStyle () {
      // this.ele 设置样式, 设置好几个
      // this.ele 下面的 .top 需要设置 好几个
      // this.ele 下面的 .bottom 需要设置 好几个
      setStyle(this.ele, {
        width: '500px',
        height: '300px',
        border: '3px solid #333',
        'background-color': '#fff',
        position: 'fixed',
        top: '0',
        left: '0',
        right: '0',
        bottom: '0',
        margin: 'auto',
        display: 'none',
        'flex-direction': 'column'
      })

      const topBox = this.ele.querySelector('.top')
      const centerBox = this.ele.querySelector('.center')
      const bottomBox = this.ele.querySelector('.bottom')
      const btn = this.ele.querySelector('button')
      setStyle(topBox, {
        height: '35px',
        display: 'flex',
        'align-items': 'center',
        'box-sizing': 'border-box',
        padding: '0 20px',
        'background-color': 'red',
        color: '#fff'
      })
      setStyle(bottomBox, {
        height: '35px',
        display: 'flex',
        'align-items': 'center',
        'box-sizing': 'border-box',
        padding: '0 20px',
        'background-color': 'red',
        color: '#fff',
        'justify-content': 'flex-end'
      })
      setStyle(centerBox, {
        flex: '1',
        display: 'flex',
        'justify-content': 'center',
        'align-items': 'center',
        'font-size': '24px'
      })
      setStyle(btn, {
        cursor: 'pointer'
      })
    }

    // 需要一个方法, 能让 div 隐藏起来
    setEvent () {
      const btn = this.ele.querySelector('button')
      btn.addEventListener('click', () => {
        this.ele.style.display = 'none'
      })
    }

    // 需要一个方法, 调整 .top 和 .bottom 的颜色
    setColors ({ color, text }) {
      const topBox = this.ele.querySelector('.top')
      topBox.style['background-color'] = color
      topBox.innerText = text
      const bottomBox = this.ele.querySelector('.bottom')
      bottomBox.style['background-color'] = color
    }

    // 需要一个方法, 调整 .center 内的文本内容
    setText (msg) {
      const centerBox = this.ele.querySelector('.center')
      centerBox.innerText = msg
    }
  }

  // 单例模式核心代码
  let instance = null
  return function (type, msg) {
    if (!instance) instance = new Dialog()
    instance.change(type, msg)
    return instance
  }
})()

     new Dialog('warning', '删除后不能恢复')
  </script>
</body>
</html>

Web Storage

cookie
认识 cookie
  • cookie中的数据 可以被同一个网站的页面所共享
  • 不同浏览器的cookie 不能共享
  • cookie的数据存储在浏览器中,每次请求服务器,在请求报文中携带cookie的数据,发送给服务器
  • 服务器端无法直接操作cookie,是通过在服务器端设置响应头的的方式,通知浏览器对cookie进行设置,
  • cookie中的数据有效期,不设置是会话级别的, 浏览器关闭,会话结束,数据销毁,可以人为设置cookie的有效期
  • cookie存储容量小,约4kb
操作cookie

一定通过服务器的方式就行访问

基本使用

语法格式

设置cookie:
document.cookie="username=John;expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
                   存储的值            有效时间                             适用范围
 注意:此处的有效期是时间字符串.
 
读取cookie
document.cookie

删除cookie
直接设置时间过期

例1:通过cookie存储name,age,addr数据

// 1. 设置, 要求 键值对, 通过 = 分隔
  document.cookie = "name=fengfeng";
  document.cookie = "age=18";
  document.cookie = "desc=shuai";  
//2. 获取, document.cookie 一次性将所有的 cookie 都获取, 以字符串的形式返回
 //通过 "; " 分隔, name=pengpeng; age=18; desc=shuai
   console.log( document.cookie );
// 获取cookie中的值
   document.cookie;

问题:一次性存储多个cookie后,没办法获取指定的

例2:设置一个cookie的hobby=maomi一分钟后过期

let d = new Date(); // 获取当前时间对象
let time = d.getTime();  // 获取时间戳
let time1 = d.setTime(时间戳); // 设置需要格式化的事件戳
let expires = d.toGMTString();  //   cookie 的有效期,计时不是按照中国时区,所以需要转化


   let d = new Date();
   let time = d.getTime(); // 单位是毫秒
   //console.log(time)

   //向后设置一分钟
   d.setTime(time+1*60*1000);
   let exp = d.toGMTString();
  // console.log(exp) 

  // 设置cookie,为一分钟过期
  // 设置cookie过期的是expires
 // document.cookie='qi=压岁钱;expires='+exp;
cookie的读取封装
class Cookie {
  // 设置cookie
  static setCookie (name, val, exp = 0) {
    // 判断是否设置时间
    if (exp) {
      let d = new Date();
      let ms = d.getTime();
      d.setTime(exp * 60 * 1000 + ms);
      // 获取且转化为时间字符串
      exp = d.toGMTString();
    }
    // cookie的设置
    document.cookie = `${name}=${val};expires=${exp}`;
  }

  // cookie的获取
 static getCookie(key) {
        // 1 判断是否传值
        if (!key) return;
        // 2 取出cookie
        // console.log(document.cookie);
        let vals = document.cookie;
        // 2-1 为空则不继续执行
        if (!vals) return null;

        // 2-2 不为空,则分割
        vals = vals.split(';');
        console.log(vals);

        // 2-3 遍历寻找目标key
        let data = '';
        // v 是数组的元素
        vals.forEach((v, i) => {
          console.log(v.trim());
          // 2-4 找到下标不为-1且为0的,就是要取的key
          //  console.log(v.trim().indexOf(key));
          if (v.trim().indexOf(key) == 0) {
            // console.log((v.split('='))[1]);
            // forEach内部函数的返回值,外部接收不到
            // return (v.split('='))[1];
            data = (v.split('='))[1];
          }
        });
        return data;
      }
}
cookie的加密

md5加密和base64的加解密

js中session操作

// 保存数据到sessionStorage
sessionStorage.setItem('key', 'value');
 
// 从sessionStorage获取数据
var data = sessionStorage.getItem('key');
 
// 从sessionStorage删除保存的数据
sessionStorage.removeItem('key');
 
// 从sessionStorage删除所有保存的数据
sessionStorage.clear();

localStorage 是js中最常见的存储方式.

cookie和session主要在服务器端使用,保存一次会话信息.PHP.java,NodeJs

面试题

本地存储(记住)

-: 说一下 cookie localStorage sessionStroage 的区别

1. 存储大小
   cookie   4KB 左右
             => localStorage/sessionStroage  20MB 左右
2 自动携带
    cookie   会跟随请求自动携带在请求头内
                => localStorage/sessionStroage   不会自动携带需要手动设置
3 时效性
    localStorage 永久
                   => sessionStroage 会话
                   => cookie 默认会话级别, 可以自定义设置过期时间
4. 存储位置
     cookie 必须依赖域名存储
                      => localStorage/sessionStroage 可以在本地状态下使用
5 前后端操作
     cookie 前后端都可以操作
                         => localStorage/sessionStroage 只能前端操作, 后端不行

6 session(补充)
  => 一个服务器端的存储空间
  => 用来支持登陆状态保持的
  => 当 session 空间开启以后, 会生成一个 sessionID 的内容自动放在 cookie 内

面试题:数组塌陷

 <script>
    var arr = [1, 2, 3, 4, 5, 6];

    // 删除数组中的元素,删除不干净
    // for (var i = 0; i < arr.length; i++) {
    //   arr.splice(i, 1)
    // }
    // console.log(arr); // 删除不干净,因为i在变化

    // 方法1: 设置删除起始位置是0
    // var length = arr.length;
    // for (var i = 0; i < length; i++) {
    //   arr.splice(0, 1)
    // }


    // 方法2:从尾巴,倒着删除
    // for (var i = arr.length - 1; i >= 0; i--) {
    //   arr.splice(i, 1)
    // }

    // 方法3:让i永远为0,永远删除第一个元素
    for (var i = 0; i < arr.length; i++) {
      arr.splice(i, 1);
      //console.log('a' + i);
      i--;
      console.log(i);
    }
    console.log(arr);


  </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值