例子_输入动物名字返回动物叫声

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

版本1.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function scream(animal) {
        var animal = animal || '';
        switch (animal){
         case '':
          return '输入一个动物名字,如:猫,狗,鸟,猪'
        		break;
          case '猫':
            return  '喵~喵~';
            break;
          case '狗':
            return  '旺旺!';
            break;
          case '鸟':
            return  '吱吱吱';
            break;
          case '猪':
            return  '噜噜噜';
            break;
          default:
           return '这种动物的叫声还没有'
           break;
        }
      }

版本2.0//键值对,天然适合 对象形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function scream(animal) {
        var animal = animal || '';
        var screamAni = {
          '猫':'喵~喵~',
          '狗':'旺旺',
          '鸟':'吱吱吱',
          '猪':'噜噜噜'
        }
        if(animal === ''){
          return '请输入动物名,比如:猫,狗,鸟,猪'
        }
        if(typeof(screamAni[animal]) !== undefined){
          return screamAni[animal];
        }
        return '还没有这种动物的叫声'
      }
这你就很搞笑了,本来以为不支持中文,
起码chorom似乎支持中文变量.

版本3.0//

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
      function scream(animal) {
        var animal = animal || '';
        var screamAni = {
          '猫':'喵~喵~',
          '狗':'旺旺',
          '鸟':'吱吱吱',
          '猪':'噜噜噜'
        }
        if(animal === ''){
          return '请输入动物名,比如:猫,狗,鸟,猪'
        }
        if(!screamAni[animal]){
          screamAni[animal] = window.prompt('还没有这种动物的叫声,请输入该动物的叫声');
          return arguments.callee(animal);
        }else{
          console.log(screamAni[animal]);
          return screamAni[animal];
          
        }
      }

我本来想功能:如果没有就补充进来,果然上面的代码是行不通的.
原因在于,执行函数时,变量重新声明,
要么让screamAni变成全局变量,要么通过闭包使其变成私有变量,

版本3.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      var scream = (function () {
        var screamAni = {
          '猫':'喵~喵~',
          '狗':'旺旺',
          '鸟':'吱吱吱',
          '猪':'噜噜噜'
        }
        return function (animal) {
          var animal = animal || '';
          if(animal === ''){
            return '请输入动物名,比如:猫,狗,鸟,猪'
          }
          if(!screamAni[animal]){
            screamAni[animal] = window.prompt('还没有这种动物的叫声,请输入该动物的叫声');
            return arguments.callee(animal);
          }else{
            console.log(screamAni[animal]);
            return screamAni[animal];
          }
        }
      })();

版本4.0//也是闭包,但我最近刚接触,有点突破脑洞 //是从一种叫惰性函数的地方来的.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var scream = function (animal) {
        var screamAni = {
          '猫':'喵~喵~',
          '狗':'旺旺',
          '鸟':'吱吱吱',
          '猪':'噜噜噜'
        }
        scream = function (animal) {//这里绝对不能 写成 var scream = function (animal){
          var animal = animal || '';
          if(animal === ''){
            return '请输入动物名,比如:猫,狗,鸟,猪'
          }
          if(!screamAni[animal]){
            screamAni[animal] = window.prompt('还没有这种动物的叫声,请输入该动物的叫声');
            return arguments.callee(animal);
          }else{
            console.log(screamAni[animal]);
            return screamAni[animal];
          
          }
        }
        return scream(animal);
      };

为什么说这个函数破脑洞呢? 
因为他在函数执行的过程当中,
改变了函数体本身.
惰性函数的应用可以减少性能消耗.
具体可以百度.

但我第一次接触这种函数体内根据情况,改写自身函数的形式,
还是感觉挺突破脑洞的.
虽然我还无法知道这个有什么用,
但下意识觉得,这让函数变得更加灵活,更有生命力?

====================================== 过了三四周回头看, 上面说的都是一个思路,都一样.. 这几天学设计模式 根据面向对象的设计模式的原则, 上面的函数,违反了开闭原则

可以这样?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
            function Animal () {
            	
            this.obj = {
            	  '狗' : "旺旺",
            	  "猫" : "喵喵",
            	  "猪" : "露露"
            	}
            
            this.scream = function (animal) {
              console.log(this.obj[animal]);
            	return this.obj[animal];
            }
            this.extend = function (opt) {
            	for(var key in opt) {
            	  this.obj[key] = opt[key];
            	}
            }
            }
            var animal = new Animal();
            
            animal.scream("狗")// "旺旺"
            
            animal.extend({"鸟":"吱吱"});// 可扩展.
            
            animal.scream("鸟")// "吱吱"

似乎,惯例是把方法,存在原型上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
            function Animal () {
            	
            this.obj = {
            	  '狗' : "旺旺",
            	  "猫" : "喵喵",
            	  "猪" : "露露"
            	}
            }
            
            Animal.prototype.scream = function (animal) {
              console.log(this.obj[animal]);
              return this.obj[animal];            	
            }
            Animal.prototype.extend = function (opt) {
              for(var key in opt) {
                this.obj[key] = opt[key];
              }
            }
            var animal = new Animal();
            animal.scream("狗")// "旺旺"
            animal.extend({"鸟":"吱吱"});
            animal.scream("鸟")// "吱吱"

联想策略模式的话, 可以这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
            function Animal () {
            	
            this.obj = {
            	  '狗' : function (cb) {
            	    cb("旺旺");
            	  },
            	  "猫" : function (cb) {
            	  	cb("旺旺");
            	  },
            	  "猪" : function (cb) {
            	  	cb("露露");
            	  }
            	}
            }
            
            function handle (value) {
            	console.log(value);
            }
            
            Animal.prototype.scream = function (animal,handle) {
               this.obj[animal](handle);	
            }
            Animal.prototype.extend = function (opt) {
              for(var key in opt) {
                this.obj[key] = opt[key];
              }
            }
            var animal = new Animal();
            
            animal.scream("狗",handle);
            
            animal.extend({
              "鸟" : function (cb) {
              	cb("吱吱")
              }
            })
            
            animal.scream("鸟",handle);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
            function Animal () {
            	
            this.obj = {
            	  '狗' : "旺旺",
            	  "猫" : "喵喵",
            	  "猪" : "露露"
            	}
            
            }
            
            function handle (value) {
            	console.log(value);
            }
            
            Animal.prototype.scream = function (animal,handle) {
              handle(this.obj[animal])
            }
            Animal.prototype.extend = function (opt) {
              for(var key in opt) {
                this.obj[key] = opt[key];
              }
            }
            var animal = new Animal();
            
            animal.scream("狗",handle);
            
            animal.extend({
              "鸟" : "吱吱"
            })
            
            animal.scream("鸟",handle);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
            function Animal () {
            	
            this.obj = {
            	  '狗' : "旺旺",
            	  "猫" : "喵喵",
            	  "猪" : "露露"
            	}
            this.cache = [];
            }
            
            function handle (value) {
            	console.log(value);
            }
            
            Animal.prototype.add = function (animal,handle) {
              var self = this;
              this.cache.push(function () {
                handle(self.obj[animal])
              })
            }
            Animal.prototype.extend = function (opt) {
              for(var key in opt) {
                this.obj[key] = opt[key];
              }
            }
            
            Animal.prototype.scream = function () {
            	for(var i = 0; i < this.cache.length ; i++) {
            	  this.cache[i]()
            	}
            }
            
            
            var animal = new Animal();
            
            animal.add("狗",handle);
            animal.scream();
            animal.extend({
              "鸟" : "吱吱"
            })
            animal.add("鸟",handle);
            animal.scream();

// 但是不好从 cache 那里 删除相应的函数, 我们可以考虑 让cache = {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
            function Animal () {
            	
            this.obj = {
            	  '狗' : "旺旺",
            	  "猫" : "喵喵",
            	  "猪" : "露露"
            	}
            this.cache = {};
            }
            
            function handle (value) {
            	console.log(value);
            }
            
            Animal.prototype.add = function (animal,handle) {
              var self = this;
              this.cache[animal]= function () {
                handle(self.obj[animal])
              }
            }
            Animal.prototype.extend = function (opt) {
              for(var key in opt) {
                this.obj[key] = opt[key];
              }
            }
            
            Animal.prototype.scream = function () {
            	for(var key in this.cache) {
            	  this.cache[key] && this.cache[key]();
            	}
            }
            Animal.prototype.remove = function (animal) {
            	this.cache[animal] = null;
            }
            
            
            var animal = new Animal();
            
            animal.add("狗",handle);
            animal.scream();
            animal.extend({
              "鸟" : "吱吱"
            })
            animal.add("鸟",handle);
            animal.scream();
            animal.remove("狗");
            animal.scream();

但有时,我们希望一次触发多个.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
            function Animal () {
            	
            this.obj = {
            	  '狗' : "旺旺",
            	  "猫" : "喵喵",
            	  "猪" : "露露"
            	}
            this.cache = {};
            }
            
            function handle (value) {
            	console.log(value);
            }
            
            Animal.prototype.add = function (animal,handle) {
              var self = this;
              if (Array.isArray(this.cache[animal])) {
              	this.cache[animal].push(function () {
              		handle(self.obj[animal]);
              	})
              }else{
                this.cache[animal] = [function () {
                  handle(self.obj[animal]);
                }];
              }
            }
            Animal.prototype.extend = function (opt) {
              for(var key in opt) {
                this.obj[key] = opt[key];
              }
            }
            
            Animal.prototype.scream = function (animal) {
            	var len = this.cache[animal].length;
            	for(var i = 0; i < len ; i++) {
            	  this.cache[animal][i]();
            	}
            }
            Animal.prototype.remove = function (animal) {
            	this.cache[animal] = [];
            }
            
            
            var animal = new Animal();
            
            animal.add("狗",handle);
            animal.scream("狗");
            animal.extend({
              "鸟" : "吱吱"
            })
            animal.add("鸟",handle);
            animal.scream("鸟");
            animal.remove("狗");
            animal.scream("狗");

以上只是回顾一下,设计模式里的一些内容. 感觉整体结构不是很清晰. 凑合看吧.

不过这里能看出一些东西. 设计模式那里有讲过, 使用设计模式的一些结构, 是会增加复杂度和耦合度的. 但好处是, 可扩展性高, 维护性高. 而且越是扩展时,就越是会有积极作用.