2019.6.22 Web全栈开发 学习笔记(十七)

JavaScript Day 10

上课日期:2019年8月29日

课程内容

一、JavaScript中的模式

  1. 工厂模式
function factory() {
        var args = arguments;
        //实例化对象   返回对象
        var obj = new Object();
        //封装属性以及方法
        obj.name = args[0];
        obj.sex = args[1];
        obj.age = args[2];
        obj.sleep = function () {
            return this.name + "会睡觉";
        }
        return obj;
    }

形如以上的这个模式就是工厂模式,即函数里面返回单个对象,在使用时,可以用以下这种形式

var person = factory("HHD", "男", 20);
    console.log(person);

输出结果是一个name属性为HHD,sex属性为男,age属性为20,再加上一个sleep方法的对象。
{name: “HHD”, sex: “男”, age: 20, sleep: ƒ}
这种模式的缺点是:没办法区分对象的类型

  1. 构造函数模式

我们之前常用的就是这种模式,就是直接在函数上写对象,形式如下

function Person() {
        this.name = arguments[0];
        this.sex = arguments[1];
        this.age = arguments[2];
        this.eat = function () {
            return this.name + "会吃饭!";
        }
    }

其中,this在正常的js代码中指代的是window,在对象实例化后指代的是当前的对象。
在使用时,可以用如下的方式

var son = new Person("HHD", "男", 20);
    console.log(son);

输出结果与上面不同的是
Person {name: “HHD”, sex: “男”, age: 20, eat: ƒ}
前面多了一个Person,即我们定义的类型,这就体现出了这种模式的优点,也就是可以区分类型。
而这个模式的缺点就是每个方法在每个实例上面都需要重新定义一遍。

  1. 原型模式

这种模式是建立在构造函数模式基础之上的,形式如下

function animal() {
        this.name = arguments[0];
        this.sex = arguments[1];
        this.type = arguments[2]
    }
    animal.prototype = {
        constructor: animal,
        eat: function () {
            return this.name + "会吃";
        },
        sleep: function () {
            return this.name + "会睡觉";
        },
        info: function () {
            return this.name + "属于:" + this.type + ",性别:" + this.sex;
        }
    }

在定义函数后可以用prototype进行追加,使用时

var cat = new animal("喵喵", "母", "猫科");
    var mouse = new animal("米奇", "公", "鼠科");
    console.log(cat, mouse);

输出结果:
animal {name: “喵喵”, sex: “母”, type: “猫科”}
animal {name: “米奇”, sex: “公”, type: “鼠科”}
这种方法的特点是会导致所有的原型属性以及方法全部共享。

  1. 动态原型模式

这种模式可以通过相关属性动态添加原型 (检测原型是否存在)

function Animal(name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.speak = "我会说话";
        if (typeof this.speak != "function") {
            Animal.prototype.sleep = function () {
                console.log(this.name + "在睡觉");
            };
        }
    }

    var snack = new Animal("小蛇", 2, '爬');
    console.log(snack);
  1. 单例模式

可以简单理解为返回一个对象

function Instance(name, sex, age) {
        var instance = null;

        function Animal() {
            this.name = arguments[0];
            this.sex = arguments[1];
            this.age = arguments[2];
        }

        if (instance == null) {
            instance = new Animal(name, sex, age);
        }
        return instance;
    }
    var cat = Instance("咪咪", "母", 2);
    console.log(cat);

输出结果Animal {name: “咪咪”, sex: “母”, age: 2}

  1. 模块模式

这种模式类似于代码块的封装

var model = (function () {
        var instance = null;
        var person = null;

        function Animal() {
            this.name = arguments[0];
            this.sex = arguments[1];
            this.age = arguments[2];
        }

        function Person() {
            this.name = arguments[0];
            this.sex = arguments[1];
            this.age = arguments[2];
        }

        if (person == null) {
            person = new Person("maodou", "男", 18);
        }
        if (instance == null) {
            instance = new Animal("cat", "母", 2);
        }

        return {
            instance: instance,
            person: person
        }
    })()
    console.log(model);

输出结果
{instance: Animal, person: Person}
里面有:
instance: Animal {name: “cat”, sex: “母”, age: 2}
person: Person {name: “maodou”, sex: “男”, age: 18}
__ proto __: Object

二、原型链

先写一个Animal构造函数,追加原型对象

function Animal(){
        this.name="小猫";
        this.sex="母";
    }
    //原型对象
    Animal.prototype={
        constructor:Animal,
        sleep:function (){
            return "会睡觉"
        }
    }

    var cat=new Animal();
    console.log(cat)

输出结果为Animal
name: “小猫”
sex: “母”
__ proto__:
constructor: ƒ Animal()
sleep: ƒ ()
__ proto__:
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__ defineGetter__: ƒ __ defineGetter__()
__ defineSetter__: ƒ __ defineSetter__()
__ lookupGetter__: ƒ __ lookupGetter__()
__ lookupSetter__: ƒ __ lookupSetter__()
get __ proto__: ƒ __ proto__()
set __ proto__: ƒ __ proto__()

其中,__ proto__就是原型链
原型链图解

三、案例:js实现简易贪吃蛇

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
<script>
    /*
     * 画地图
     * */
    var map;
    var snack;
    var food;
    var times;
    function getMap() {
        var instance = null;

        function Map() {
            this.width = 900;
            this.height = 600;
            this.bgColor = "#000";
            this._map = null;
            this.createMap = function () {
                if (this._map == null) {
                    this._map = document.createElement("div");
                    this._map.style.background = this.bgColor;
                    this._map.style.position = "relative";
                    this._map.style.height = this.height + "px";
                    this._map.style.width = this.width + "px";
                    document.body.appendChild(this._map);
                }
            }
        }

        if (instance == null) {
            //实例化
            instance = new Map();
        }
        return instance;
    }
    function getSnack() {
        var instance = null;

        function Snack() {
            this.width = 30;
            this.height = 30;
            this._snack = [[3, 1, "red", null], [2, 1, "yellow", null], [1, 1, "yellow", null]];
            this.direct = "right";
            this.createSnack = function () {
                for (var i = 0; i < this._snack.length; i++) {
                    if (this._snack[i][3] == null) {
                        this._snack[i][3] = document.createElement("div");
                        this._snack[i][3].style.width = this.width + "px";
                        this._snack[i][3].style.height = this.height + "px";
                        this._snack[i][3].style.position = "absolute";
                        this._snack[i][3].style.background = this._snack[i][2];
                        map._map.appendChild(this._snack[i][3]);
                    }
                    this._snack[i][3].style.left = this._snack[i][0] * this.width + "px";
                    this._snack[i][3].style.top = this._snack[i][1] * this.height + "px";
                }
            }
            this.snackMove = function () {
                //属性传递
                var len = this._snack.length - 1;
                for (var i = len; i > 0; i--) {
                    this._snack[i][0] = this._snack[i - 1][0];
                    this._snack[i][1] = this._snack[i - 1][1];
                }
                //蛇头移动  方向
                switch (this.direct) {
                    case "right":
                        this._snack[0][0] += 1;
                        break;
                    case "left":
                        this._snack[0][0] -= 1;
                        break;
                    case "up":
                        this._snack[0][1] -= 1;
                        break;
                    case "down":
                        this._snack[0][1] += 1;
                        break;
                }
                //判断蛇有没有吃到食物
                if (this._snack[0][0] == food.x && this._snack[0][1] == food.y) {
                    food.createfood();
                    this._snack.push([
                        this._snack[this._snack.length - 1][0],
                        this._snack[this._snack.length - 1][1],
                        "yellow",
                        null
                    ]);
                }
                //判断蛇穿墙
                if (this._snack[0][0] >= 30) {
                    this._snack[0][0] = 0;
                }
                if (this._snack[0][0] < 0) {
                    this._snack[0][0] = 29;
                }
                if (this._snack[0][1] >= 20) {
                    this._snack[0][1] = 0;
                }
                if (this._snack[0][1] < 0) {
                    this._snack[0][1] = 19;
                }
                //撞自己撞死
                for (var i = 1; i < this._snack.length; i++) {
                    if (this._snack[0][0] == this._snack[i][0] && this._snack[0][1] == this._snack[i][1]) {
                        clearInterval(times);
                        alert("GAME OVER!");
                        return;

                    }
                }
                this.createSnack();

            }
        }

        if (instance == null) {
            instance = new Snack();
        }
        return instance;
    }

    function getFood() {
        var instance = null;

        function food() {
            this.width = 30;
            this.height = 30;
            this.bgcolor = "green";
            this._food = null;
            this.x;
            this.y;
            this.createfood = function () {
                this.x = Math.floor(Math.random() * 30);
                this.y = Math.floor(Math.random() * 20);
                if (this._food == null) {
                    this._food = document.createElement("div");
                    this._food.style.position = "absolute";
                    this._food.style.width = this.width + "px";
                    this._food.style.height = this.height + "px";
                    this._food.style.background = this.bgcolor;
                    map._map.appendChild(this._food);
                }
                this._food.style.left = this.x * this.width + "px";
                this._food.style.top = this.y * this.height + "px";
            }
        }

        if (instance == null) {
            instance = new food();
        }
        return instance;
    }
    window.onload = function () {
        map = getMap();
        map.createMap();
        snack = getSnack();
        snack.createSnack();

        food = getFood();
        food.createfood();

        times = setInterval(function () {
            snack.snackMove();
        }, 200);
        //按键
        document.body.onkeypress = function (e) {
            switch (e.key) {
                case "w":
                    if (snack.direct != "down") {
                        snack.direct = "up";
                    }
                    break;
                case "a":
                    if (snack.direct != "right") {
                        snack.direct = "left";
                    }
                    break;
                case "d":
                    if (snack.direct != "left") {
                        snack.direct = "right";
                    }
                    break;
                case "s":
                    if (snack.direct != "up") {
                        snack.direct = "down";
                    }
                    break;
            }
        }

    }
</script>
</body>
</html>
整理自尚硅谷视频教程springboot高级篇,并增加部分springboot2.x的内容 一、Spring Boot与缓存 一、JSR107 Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。 • CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可 以在运行 期访问多个CachingProvider。 • CacheManager定义了创建、配置、获取、管理和控制多个唯一命名 的Cache,这些Cache 存在于CacheManager的上下文中。一个CacheManager仅被一个 CachingProvider所拥有。 • Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个 Cache仅被一个 CacheManager所拥有。 • Entry是一个存储在Cache中的key-value对。 • Expiry 每一 个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期 的状态。一旦过期,条 目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。 二、Spring缓存抽象 Spring从3.1开始定义了org.springframework.cache.Cache 和 org.springframework.cache.CacheManager接口来统一不同的缓存技术; 并支持使用JCache(JSR- 107)注解简化我们开发; • Cache接口为缓存的组件规范定义,包含缓存的各种操作集合; • Cache接 口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache 等; • 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否 已经被调用 过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法 并缓存结果后返回给用户。下 次调用直接从缓存中获取。 • 使用Spring缓存抽象时我们需要关注以下两点; 1、确定方法需要被缓存 以及他们的缓存策略 2、从缓存中读取之前缓存存储的数据 Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、 ConcurrentMapCache等 CacheManager 缓存管理器,管理各种缓存(Cache)组件 @Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 @CacheEvict 清空缓存 @CachePut 保证方法被调用,又希望结果被缓存。 @EnableCaching 开启基于注解的缓存 keyGenerator 缓存数据时key生成策略 serialize 缓存数据时value序列化策略 @CacheConfig 抽取缓存的公共配置 三、几个重要概念&缓存注解 1、常用注解 2、常用参数 名字 位置 描述 示例 methodName root object 当前被调用的方法名 #root.methodName method root object 当前被调用的方法 #root.method.name target root object 当前被调用的目标对象 #root.target targetClass root object 当前被调用的目标对象类 #root.targetClass args root object 当前被调用的方法的参数列表 #root.args[0] 3、常用参数SPEL说明 名字 位置 描述 示例 caches root object 当前方法调用使用的缓存列表(如 @Cacheable(value= {"cache1","cache2"}) ), 则有两 个cache #root.caches[0].name argument name evaluation context 方法参数的名字. 可以直接 #参数 名 ,也可以使用 #p0或#a0 的形 式,0代表参数的索引; #iban 、 #a0 、 #p0 result evaluation context 方法执行后的返回值(仅当方法执 行之后的判断有效,如‘unless’ , ’cache put’的表达式 ’cache evict’的表达式 beforeInvocation=false ) #result 四、代码中使用缓存 1、搭建基本环境 1、导入数据库文件 创建出department和employee表 2、创建javaBean封装数据 3、整合MyBatis操作数据库 1.配置数据源信息 2.使用注解版的MyBatis; 1)、@MapperScan指定需要扫描的mapper接口所在的包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值