抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Mr.wang

Time flies and people come and go

复杂函数的学习,generator,斐波那契数列,Observer(订阅模式)

简单递归

求n! 即,1×2×3×4×5×······×n

1
function n(i){return i<2?1:i*n(i-1);}

求1+2+···+n

1
function p(i){return i<2?1:i+p(i-1);}

求和

1
2
3
4
function sum(n) {
if (n == 1) return 1
return sum(n - 1) + n
}

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
function clone(o) {
var temp = {}
for (var key in o) {
if (typeof o[key] == 'object') {
temp[key] = clone(o[key])
} else {
temp[key] = o[key]
}
}
return temp
}

求n个整数的平均值

1
2
3
4
5
6
function getEverage(n){
if(n==1){
return 1;
}
return (getEverage(n-1)*(n-1)+n)/n
}

generator

利用for...of循环,可以写出遍历任意对象(object)的方法。原生的 JavaScript 对象没有遍历接口,无法使用for...of循环,通过 Generator 函数为它加上这个接口,就可以用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function* objectEntries(obj) {
let propKeys = Reflect.ownKeys(obj);

for (let propKey of propKeys) {
yield [propKey, obj[propKey]];
}
}

let jane = { first: 'Jane', last: 'Doe' };

for (let [key, value] of objectEntries(jane)) {
console.log(`${key}: ${value}`);
}
// first: Jane
// last: Doe

将 Generator 函数加到对象的Symbol.iterator属性上面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function* objectEntries() {
let propKeys = Object.keys(this);

for (let propKey of propKeys) {
yield [propKey, this[propKey]];
}
}

let jane = { first: 'Jane', last: 'Doe' };

jane[Symbol.iterator] = objectEntries;

for (let [key, value] of jane) {
console.log(`${key}: ${value}`);
}
// first: Jane
// last: Doe

斐波那契数列

1
2
3
4
5
6
7
8
9
10
11
12
function* fibonacci() {
let [prev, curr] = [0, 1];
for (;;) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}

for (let n of fibonacci()) {
if (n > 1000) break;
console.log(n);
}

Observer(订阅-发布者)

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

"use strict";
var publisher = {
//订阅者数组上每个事件(type)有着序列化的订阅事件
subscribers: {
any: [] // event type: subscribers
},
//签订订阅服务-订阅那个类型的报纸,报纸出版自动触发订阅者的fn
subscribe: function (fn, type) {
type = type || 'any';
if (typeof this.subscribers[type] === "undefined") {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
// console.log("subscribe", this.subscribers);
},
unsubscribe: function (fn, type) {
this.visitSubscribers('unsubscribe', fn, type);
},
//发布报纸
publish: function (publication, type) {
this.visitSubscribers('publish', publication, type);
},
visitSubscribers: function (action, arg, type) {
//判断是哪个事件类型(pubtype)
//subscribers是哪个订阅者数组subscribers(对象)—>[pubtype]订阅者
//事件类型的所有事件length(max)
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max = subscribers.length;

for (i = 0; i < max; i += 1) {
if (action === 'publish') {
//事件调用
subscribers[i](arg);
} else {
if (subscribers[i] === arg) {
//删除事件
subscribers.splice(i, 1);
}
}
}
}
};

/*
var s1 = {log: console.log},
s2 = {err: console.error},
s3 = {warn: console.warn};


publisher.subscribe(s1.log);
publisher.subscribe(s2.err);
publisher.subscribe(s3.warn);

publisher.publish({hello: "World"});

publisher.unsubscribe(s2.err);
publisher.publish("hello");


publisher.subscribe(s1.log, "log");
publisher.publish({obj: "log this object"}, "log");
*/
//浅拷贝一个发布者 继承publisher所有事件且subscribers定义为{any: []}
//
function makePublisher(o) {
var i;
for (i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
o[i] = publisher[i];
}
}
o.subscribers = {any: []};
}

var paper = {
daily: function () {
this.publish("big news today");
},
monthly: function () {
this.publish("interesting analysis", "monthly");
}
};

makePublisher(paper);
//订阅者
var joe = {
drinkCoffee: function (paper) {
console.log('Just read ' + paper);
},
sundayPreNap: function (monthly) {
console.log('About to fall asleep reading this ' + monthly);
}
};
//订阅日报和月报
paper.subscribe(joe.drinkCoffee);
paper.subscribe(joe.sundayPreNap, 'monthly');
//paper出版报纸->将通知订阅者
paper.daily();
paper.daily();
paper.daily();
paper.monthly();

//每个订阅者可自行发布
makePublisher(joe);
//一个发布的publish函数
joe.tweet = function (msg) {
this.publish(msg);
};

//报纸读取这个推特
paper.readTweets = function (tweet) {
console.log('Call big meeting! Someone ' + tweet);
};

joe.subscribe(paper.readTweets);

joe.tweet("hated the paper today");

按键游戏

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
var publisher = {
subscribers: {
any: []
},
on: function (type, fn, context) {
type = type || 'any';
fn = typeof fn === "function" ? fn : context[fn];

if (typeof this.subscribers[type] === "undefined") {
this.subscribers[type] = [];
}
this.subscribers[type].push({fn: fn, context: context || this});
},
remove: function (type, fn, context) {
this.visitSubscribers('unsubscribe', type, fn, context);
},
fire: function (type, publication) {
this.visitSubscribers('publish', type, publication);
},
visitSubscribers: function (action, type, arg, context) {
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max = subscribers ? subscribers.length : 0;

for (i = 0; i < max; i += 1) {
if (action === 'publish') {
subscribers[i].fn.call(subscribers[i].context, arg);
} else {
if (subscribers[i].fn === arg && subscribers[i].context === context) {
subscribers.splice(i, 1);
}
}
}
}
};


function makePublisher(o) {
var i;
for (i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
o[i] = publisher[i];
}
}
o.subscribers = {any: []};
}

var game = {

keys: {},

addPlayer: function (player) {
var key = player.key.toString().charCodeAt(0);
this.keys[key] = player;
},

handleKeypress: function (e) {
e = e || window.event; // IE
if (game.keys[e.which]) {
game.keys[e.which].play();
}
},

handlePlay: function (player) {
var i,
players = this.keys,
score = {};

for (i in players) {
if (players.hasOwnProperty(i)) {
score[players[i].name] = players[i].points;
}
}
this.fire('scorechange', score);
}
};

function Player(name, key) {
this.points = 0;
this.name = name;
this.key = key;
this.fire('newplayer', this);
}

Player.prototype.play = function () {
this.points += 1;
this.fire('play', this);
};

var scoreboard = {

element: document.getElementById('results'),

update: function (score) {

var i, msg = '';
for (i in score) {
if (score.hasOwnProperty(i)) {
msg += '<p><strong>' + i + '<\/strong>: ';
msg += score[i];
msg += '<\/p>';
}
}
this.element.innerHTML = msg;
}
};


makePublisher(Player.prototype);
makePublisher(game);

Player.prototype.on("newplayer", "addPlayer", game);
Player.prototype.on("play", "handlePlay", game);

game.on("scorechange", scoreboard.update, scoreboard);

window.onkeypress = game.handleKeypress;


var playername, key;
while (1) {
playername = prompt("Add player (name)");
if (!playername) {
break;
}
while (1) {
key = prompt("Key for " + playername + "?");
if (key) {
break;
}
}
new Player(playername, key);
}

评论