Menu
Woocommerce Menu

银河国际网址手机版简单粗暴地理解,图例详解那道setTimeout与循环闭包的经典面试题

0 Comment


教你用 HTML5 制作Flappy Bird(上)

2014/03/22 · HTML5,
JavaScript · 5
评论 ·
HTML5,
Javascript

本文由 伯乐在线 –
杨帅
翻译。未经许可,禁止转载!
印度语印尼语出处:lessmilk。迎接加入翻译组。

粗粗在七个月前,作者给本身定了二个对象:每一周在构建二个HTML5新游戏。结束近年来,笔者已经有了9款游戏。今后无数人可望本人能写一下哪些创制这个游戏,在这篇文章中,让我们来四只用HTML5制作Flappy
Bird。

银河国际网址手机版 1

Flappy
Bird是一款相当美丽且易于上手的玩乐,可以当做三个很好的HTML5嬉戏的科目。在那片教程中,我们接纳Phaser框架写三个唯有65行js代码的简化版Flappy
Bird。

点击此处能够先感受一下咱们即将在制作的娱乐。

提示1:你得会JavaScript
提示2:想上学更多关于Phaser框架的学识可以看这篇作品getting started
tutorial(近些日子做事忙,稍后翻译)

简单来说残暴地领会 JS 原型链

2016/05/07 · JavaScript
· 1 评论 ·
原型链

最早的小说出处:
茄果   

原型链掌握起来有个别绕了,网络资料也是大多,每一遍午夜睡不着的时候总喜欢在网络找点原型链和闭包的篇章看,效果极好。

绝不纠结于那一群术语了,那除了让您脑子拧成麻花,真的不可能帮你哪些。轻巧狠毒点看原型链吧,想点与代码非亲非故的事,举例人、妖以及人妖。

1)人是人她妈生的,妖是妖他妈生的。人和妖都以目的实例,而人她妈和妖他妈就是原型。原型也是指标,叫原型对象。

银河国际网址手机版 2

2)人她妈和人她爸滚床单能生出一批人小鬼、妖他妈和妖他爸啪啪啪能生出一群妖婴孩,交欢正是构造函数,俗称造人。

银河国际网址手机版 3

3)人她妈会记录做爱的音讯,所以能够由这个人她妈找到交合的新闻,也正是说能通过原型对象找到构造函数。

4)人她妈能够生相当多宝物,但那么些珍宝独有多少个老妈,这就是原型的独一性。

5)人她妈也是由人她妈他妈生的,通过人她妈找到人她妈他妈,再通过人她妈他妈找到人她妈他妈……,那一个涉及叫做原型链。

银河国际网址手机版 4

6)原型链并非最为的,当你通过人她妈一贯往上找,最终开采你会开采人他妈他妈他妈……的他妈都不是人,相当于原型链最后指向null。

7)人她妈生的人会有人的轨范,妖他妈生的妖会有妖的丑陋,那叫接轨。

银河国际网址手机版 5

8)你承接了你妈的肤色,你妈传承了你妈他妈的肤色,你妈他妈……,这正是原型链的接续。

9)你谈指标了,她妈令你带上房产证去提货,你若没有,那他妈会问您妈有未有,你妈未有那她妈会问你妈她妈有未有……这就是原型链的向上寻找。

10)你会接二连三你妈的旗帜,不过你也得以去染发洗剪吹,便是说对象的质量能够自定义,会覆盖继承获得的性质。

银河国际网址手机版 6

11)即便您洗剪吹了染成黄毛了,但你不能够退换你妈的样板,你妈生的兄弟小妹跟你的黄毛洗剪吹没一点提到,就是说对象实例不能够改换原型的属性。

12)可是你家被你玩火烧了的话,那正是说你家你妈家你弟们家都被烧了,那正是原型属性的分享。

13)你妈别名阿珍,邻居姨妈都叫您阿珍儿,但您妈头发从飘柔做成了金毛狮王后,隔壁大婶都改口叫你包租仔,那叫原型的动态性。

银河国际网址手机版 7

14)你妈爱美,又跑到大韩民国时代整形,整到你妈他妈都认不出来,尽管你妈头发换回飘柔了,但隔壁邻居还是叫你金毛狮王子。因为没人认出你妈,整形后的你妈已经回炉再造了,那便是原型的一体化重写。

银河国际网址手机版 8

尼玛!你特么也是够了! Don’t BB! Show me the code!

function Person (name) { this.name = name; } function Mother () { }
Mother.prototype = { //Mother的原型 age: 18, home: [‘Beijing’,
‘Shanghai’] }; Person.prototype = new Mother(); //Person的原型为Mother
//用chrome调节和测量试验工具查看,提供了__proto__接口查看原型,这里有两层原型,各位依旧平昔看chrome好一点。
var p1 = new Person(‘杰克’); //p1:’杰克’;
__proto__:{__proto__:18,[‘Beijing’,’Shanghai’]} var p2 = new
Person(‘Mark’); //p2:’Mark’;
__proto__:{__proto__:18,[‘Beijing’,’Shanghai’]} p1.age = 20;
/* 实例不可能改造原型的为主值属性,正如你洗剪吹染黄毛跟你妈非亲非故 *
在p1实例下增添二个age属性的一般操作,与原型无关。跟var o={};
o.age=20同等。 * p1:上边多了个属性age,而__proto__跟
Mother.prototype一样,age=18。 * p2:独有属性name,__proto__跟
Mother.prototype一样 */ p1.home[0] = ‘Shenzhen’; /*
原型中援用类型属性的分享,正如你烧了你家,正是烧了你全家的家 *
那几个先过,下文再细致唠叨一下可好? * p1:’Jack’,20;
__proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/ p1.home = [‘Hangzhou’, ‘Guangzhou’]; /*
其实跟p1.age=20一模一样的操作。换到这么些驾驭: var o={};
o.home=[‘big’,’house’] * p1:’Jack’,20,[‘Hangzhou’,’Guangzhou’];
__proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/ delete p1.age; /*
删除实例的性质之后,原来被覆盖的原型值就重见天日了。正如你剃了光头,遗传的使人迷恋小卷发就长出来了。
*
那正是发展寻觅机制,先搜你,然后你妈,再你妈他妈,所以你妈的改造会动态影响您。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/ Person.prototype.lastName = ‘Jin’; /*
改写原型,动态反馈到实例中。正如您妈变新潮了,邻居谈到你都说你妈真潮。
*
注意,这里大家改写的是Person的原型,就是往Mother里加贰个lastName属性,等同于Mother.lastName=’Jin’
*
这里并非改Mother.prototype,改换区别的等级次序,效果往往会有十分的大的差异。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’;
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} */
Person.prototype = { age: 28, address: { country: ‘USA’, city:
‘Washington’ } }; var p3 = new Person(‘Obama’); /*
重写原型!这一年Person的原型已经完全成为叁个新的对象了,也正是说Person换了个妈,叫后妈。
* 换到那样掌握:var a=10; b=a; a=20;
c=a。所以b不改变,变得是c,所以p3跟着后妈变化,与亲妈无关。 *
p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’;
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’} */
Mother.prototype.no = 9527; /*
改写原型的原型,动态反馈到实例中。正如您妈他妈变新潮了,邻居聊起你都说你丫姑外婆真潮。
*
注意,这里大家改写的是Mother.prototype,p1p2会变,但地点p3跟亲妈已经了无瓜葛了,不影响她。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527} *
p2:’Mark’;
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527} *
p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’} */
Mother.prototype = { car: 2, hobby: [‘run’,’walk’] }; var p4 = new
Person(‘Tony’); /*
重写原型的原型!那一年Mother的原型已经完全成为二个新的目的了!人她妈换了个后妈!
*
由于位置Person与Mother已经断开联系了,那时候Mother怎么变已经不影响Person了。
* p4:’Tony’;__proto__: 28 {country: ‘USA’, city: ‘Washington’} */
Person.prototype = new Mother(); //再度绑定 var p5 = new
Person(‘Luffy’); //
那一年假诺急需运用这一个改变的话,那就要重复将Person的原型绑到mother上了
// p5:’Luffy’;__proto__:{__proto__: 2, [‘run’,’walk’]}
p1.__proto__.__proto__.__proto__.__proto__
//null,你说原型链的极限不是null?
Mother.__proto__.__proto__.__proto__
//null,你说原型链的终极不是null?

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
function Person (name) { this.name = name; }
function Mother () { }
Mother.prototype = {    //Mother的原型
    age: 18,
    home: [‘Beijing’, ‘Shanghai’]
};
Person.prototype = new Mother(); //Person的原型为Mother
 
//用chrome调试工具查看,提供了__proto__接口查看原型,这里有两层原型,各位还是直接看chrome好一点。
var p1 = new Person(‘Jack’); //p1:’Jack’; __proto__:{__proto__:18,[‘Beijing’,’Shanghai’]}
var p2 = new Person(‘Mark’); //p2:’Mark’; __proto__:{__proto__:18,[‘Beijing’,’Shanghai’]}
 
p1.age = 20;  
/* 实例不能改变原型的基本值属性,正如你洗剪吹染黄毛跟你妈无关
* 在p1实例下增加一个age属性的普通操作,与原型无关。跟var o={}; o.age=20一样。
* p1:下面多了个属性age,而__proto__跟 Mother.prototype一样,age=18。
* p2:只有属性name,__proto__跟 Mother.prototype一样
*/
 
p1.home[0] = ‘Shenzhen’;
/* 原型中引用类型属性的共享,正如你烧了你家,就是烧了你全家的家
* 这个先过,下文再仔细唠叨一下可好?
* p1:’Jack’,20; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;    __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
p1.home = [‘Hangzhou’, ‘Guangzhou’];
/* 其实跟p1.age=20一样的操作。换成这个理解: var o={}; o.home=[‘big’,’house’]
* p1:’Jack’,20,[‘Hangzhou’,’Guangzhou’]; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                             __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
delete p1.age;    
/* 删除实例的属性之后,原本被覆盖的原型值就重见天日了。正如你剃了光头,遗传的迷人小卷发就长出来了。
* 这就是向上搜索机制,先搜你,然后你妈,再你妈他妈,所以你妈的改动会动态影响你。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                          __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
 
Person.prototype.lastName = ‘Jin’;
/* 改写原型,动态反应到实例中。正如你妈变新潮了,邻居提起你都说你妈真潮。
* 注意,这里我们改写的是Person的原型,就是往Mother里加一个lastName属性,等同于Mother.lastName=’Jin’
* 这里并不是改Mother.prototype,改动不同的层次,效果往往会有很大的差异。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                          __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
Person.prototype = {
    age: 28,
    address: { country: ‘USA’, city: ‘Washington’ }
};
var p3 = new Person(‘Obama’);
/* 重写原型!这个时候Person的原型已经完全变成一个新的对象了,也就是说Person换了个妈,叫后妈。
* 换成这样理解:var a=10; b=a; a=20; c=a。所以b不变,变得是c,所以p3跟着后妈变化,与亲妈无关。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                          __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’}
*/
 
 
Mother.prototype.no = 9527;
/* 改写原型的原型,动态反应到实例中。正如你妈他妈变新潮了,邻居提起你都说你丫外婆真潮。
* 注意,这里我们改写的是Mother.prototype,p1p2会变,但上面p3跟亲妈已经了无瓜葛了,不影响他。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527}
* p2:’Mark’;                          __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527}
* p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’}
*/
 
Mother.prototype = {
    car: 2,
    hobby: [‘run’,’walk’]
};
var p4 = new Person(‘Tony’);
/* 重写原型的原型!这个时候Mother的原型已经完全变成一个新的对象了!人他妈换了个后妈!
* 由于上面Person与Mother已经断开联系了,这时候Mother怎么变已经不影响Person了。
* p4:’Tony’;__proto__: 28 {country: ‘USA’, city: ‘Washington’}
*/
Person.prototype = new Mother(); //再次绑定
var p5 = new Person(‘Luffy’);
// 这个时候如果需要应用这些改动的话,那就要重新将Person的原型绑到mother上了
// p5:’Luffy’;__proto__:{__proto__: 2, [‘run’,’walk’]}
 
p1.__proto__.__proto__.__proto__.__proto__ //null,你说原型链的终点不是null?
Mother.__proto__.__proto__.__proto__    //null,你说原型链的终点不是null?

看完基本能清楚了啊?

今天再来讲说 p1.age = 20、p1.home = [‘Hangzhou’, ‘Guangzhou’]
和  p1.home[0] = ‘Shenzhen’ 的区别。 p1.home[0] = ‘Shenzhen’;
 总计一下是 p1.object.method,p1.object.property 这么的格局。

p1.age = 20;  p1.home = [‘Hangzhou’,
‘Guangzhou’];这两句仍旧比较好明白的,先忘记原型吧,想想大家是怎么为叁个数见不鲜对象扩展质量的:

var obj = new Object(); obj.name=’xxx’; obj.num = [100, 200];

1
2
3
var obj = new Object();
obj.name=’xxx’;
obj.num = [100, 200];

如此那般是还是不是就清楚了吧?一样一样的啊。

那为何 p1.home[0] = ‘Shenzhen’ 不会在 p1 下创建多个 home
数组属性,然后将其首个人设为 ‘Shenzhen’呢?
大家仍旧先忘了这么些,想想上边的obj对象,假如写成这样: var obj.name =
‘xxx’, obj.num = [100, 200],能赢得你要的结果吧?
显著,除了报错你如何都得不到。因为obj还未定义,又怎么能往里面参预东西啊?同理,p1.home[0]中的
home 在 p1 下未有被定义,所以也不可能平素一步定义 home[0]
了。假诺要在p1下创设多个 home 数组,当然是那般写了:

p1.home = []; p1.home[0] = ‘Shenzhen’;

1
2
p1.home = [];
p1.home[0] = ‘Shenzhen’;

那不正是大家最常用的不二诀要吧?

而由此 p1.home[0] =
‘Shenzhen’ 不直接报错,是因为在原型链中有贰个追寻机制。当大家输入
p1.object
的时候,原型链的寻觅机制是先在实例中找找相应的值,找不到就在原型中找,还找不到就再往上一流原型中找寻……一贯到了原型链的终端,就是到null还没找到的话,就回来贰个undefined。当大家输入 p1.home[0] 的时候,也是一模一样的搜寻机制,先物色 p1
看有没出名叫 home
的属性和格局,然后逐级提升查找。最终我们在Mother的原型里面找到了,所以修改他就一定于修改了
Mother 的原型啊。

一句话概括:p1.home[0] = ‘Shenzhen’  等同于
 Mother.prototype.home[0] = ‘Shenzhen’。

由地方的剖判能够驾驭,原型链承接的重大问题在于属性的分享,比比较多时候大家只想分享方法而并不想要分享属性,理想中各类实例应该有单独的性情。因而,原型承接就有了上边包车型客车二种改进格局:

图例详解那道set提姆eout与巡回闭包的特出面试题

2017/03/06 · JavaScript
· 1 评论 ·
settimeout,
闭包

初稿出处: 波同学   

银河国际网址手机版 9

配图与本文非亲非故

我在详细图解作用域链与闭包一文中的结尾留下了一个有关setTimeout与循环闭包的思索题。

选取闭包,修改上面包车型大巴代码,让循环输出的结果依次为1, 2, 3, 4, 5

JavaScript

for (var i=1; i<=5; i++) { setTimeout( function timer() {
console.log(i); }, i*1000 ); }

1
2
3
4
5
for (var i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log(i);
    }, i*1000 );
}

值得开心的是累累恋人在读了小说将来确实对闭包有了尤其深刻的垂询,并精确的交给了两种写法。一些仇人能够认真的翻阅笔者的篇章相同的时候二个例证多少个例证的左边练习,这种承认对本人来说实在特别感动。不过也会有局地基础稍差的意中人在读书了后头,对于那题的知晓依旧感觉到质疑,由此应一些读者老爷的须要,借此作品特意对setTimeout进行一个有关的知识共享,愿大家读完事后都能够有新的获取。

在后期学习setTimeout的时候,大家很轻易精通set提姆eout有多个参数,第叁个参数为三个函数,我们因而该函数定义就要实践的操作。第一个参数为三个日子纳秒数,表示延迟奉行的光阴。

setTimeout(function() { console.log(‘一分钟之后小编将被打字与印刷出来’) }, 1000)

1
2
3
setTimeout(function() {
    console.log(‘一秒钟之后我将被打印出来’)
}, 1000)

银河国际网址手机版 10

上例施行结果

或许过多人对于setTimeout的精晓止步于此,但要么有许三个人发觉了一部分别样的事物,并在七嘴八舌里提议了疑问。比方上海教室中的那个数字7,是怎么?

每四个setTimeout在奉行时,会再次来到二个唯一ID,上海体育地方中的数字7,便是那么些独一ID。大家在利用时,日常会选用一个变量将以此独一ID保存起来,用以传入clearTimeout,清除沙漏。

var timer = setTimeout(function() {
console.log(‘假如不排除小编,小编将会一秒以往出现。’); }, 一千)
clearTimeout(timer); // 清除之后,通过setTimeout定义的操作并不会实行

1
2
3
4
5
var timer = setTimeout(function() {
    console.log(‘如果不清除我,我将会一秒之后出现。’);
}, 1000)
 
clearTimeout(timer);  // 清除之后,通过setTimeout定义的操作并不会执行

接下去,我们还须要思考其他二个尤为重要的标题,那就是setTimeout中定义的操作,在怎么样时候奉行?为了引起大家的爱戴,大家来看看上边包车型大巴事例。

var timer = setTimeout(function() { console.log(‘setTimeout actions.’);
}, 0); console.log(‘other actions.’); //
考虑一下,当自家将setTimeout的延迟时间设置为0时,上边的实施顺序会是什么?

1
2
3
4
5
6
7
var timer = setTimeout(function() {
    console.log(‘setTimeout actions.’);
}, 0);
 
console.log(‘other actions.’);
 
// 思考一下,当我将setTimeout的延迟时间设置为0时,上面的执行顺序会是什么?

在浏览器中的console中运维试试看,很轻便就可以领会答案,固然您从未打中答案,那么本身那篇小说就值得你点一个赞了,因为接下去自身分享的小知识,恐怕会在笔试中救你一命。

在对于进行上下文的牵线中,笔者与大家大饱眼福了函数调用栈这种非常数据结构的调用个性。在此间,将会介绍另外三个特殊的队列组织,页面中保有由setTimeout定义的操作,都将身处同二个连串中相继实践。

本身用下图跟我们来得一下行列数据结构的性状。

银河国际网址手机版 11

队列:先进先出

而这一个行列施行的日子,要求等待到函数调用栈清空之后才初步实行。即具备可施行代码推行实现之后,才会起来实践由setTimeout定义的操作。而这几个操作步向队列的逐一,则由设定的延迟时间来支配。

故此在地方那个例子中,即便我们将延迟时间设置为0,它定义的操作照旧供给等待全体代码推行完成之后才起来进行。这里的延迟时间,实际不是相对于setTimeout施行这一阵子,而是相对于其余代码实施完结这一刻。所以地点的例子施行结果就极其轻松明白了。

为了扶持大家精通,再来贰个结合变量进步的越来越目不暇接的例证。如若您能够正确看出实行顺序,那么您对此函数的实行就有了比较不易的认知了,如若还不可能,就回过头去拜望其余几篇文章。

setTimeout(function() { console.log(a); }, 0); var a = 10;
console.log(b); console.log(fn); var b = 20; function fn() {
setTimeout(function() { console.log(‘setTImeout 10ms.’); }, 10); }
fn.toString = function() { return 30; } console.log(fn);
setTimeout(function() { console.log(‘setTimeout 20ms.’); }, 20); fn();

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
setTimeout(function() {
    console.log(a);
}, 0);
 
var a = 10;
 
console.log(b);
console.log(fn);
 
var b = 20;
 
function fn() {
    setTimeout(function() {
        console.log(‘setTImeout 10ms.’);
    }, 10);
}
 
fn.toString = function() {
    return 30;
}
 
console.log(fn);
 
setTimeout(function() {
    console.log(‘setTimeout 20ms.’);
}, 20);
 
fn();

银河国际网址手机版 12

上栗进行结果

OK,关于setTimeout就不经常先介绍到此处,我们回过头来看看那多个循环闭包的思虑题。

JavaScript

for (var i=1; i<=5; i++) { setTimeout( function timer() {
console.log(i); }, i*1000 ); }

1
2
3
4
5
for (var i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log(i);
    }, i*1000 );
}

借使大家直接那样写,根据setTimeout定义的操作在函数调用栈清空之后才会实行的表征,for循环里定义了5个setTimeout操作。而当这一个操作起来推行时,for循环的i值,已经先一步产生了6。由此输出结果总为6。而小编辈想要让输出结果依次实践,大家就不可能不注重闭包的性格,每便循环时,将i值保存在一个闭包中,当setTimeout中定义的操作奉行时,则做客对应闭包保存的i值就能够。

而笔者辈理解在函数中闭包决断的法则,即实施时是或不是在里边定义的函数中做客了上层功效域的变量。因而我们供给包裹一层自进行函数为闭包的多变提供标准。

就此,大家只必要2个操作就能够成功难点必要,一是行使自进行函数提供闭包条件,二是传播i值并保存在闭包中。

JavaScript

for (var i=1; i<=5; i++) { (function(i) { setTimeout( function
timer() { console.log(i); }, i*1000 ); })(i) }

1
2
3
4
5
6
7
8
for (var i=1; i<=5; i++) {
 
    (function(i) {
        setTimeout( function timer() {
            console.log(i);
        }, i*1000 );
    })(i)
}

银河国际网址手机版 13

行使断点调试,在chrome中查阅施行顺序与每四个闭包中区别的i值

自然,也足以在setTimeout的首先个参数处选择闭包。

JavaScript

for (var i=1; i<=5; i++) { setTimeout( (function(i) { return
function() { console.log(i); } })(i), i*1000 ); }

1
2
3
4
5
6
7
for (var i=1; i<=5; i++) {
    setTimeout( (function(i) {
        return function() {
            console.log(i);
        }
    })(i), i*1000 );
}

1 赞 6 收藏 1
评论

银河国际网址手机版 14

设置

先下载我为教程制作的模板,里面包含:

  • phaser.min.js, 简化了的Phaser框架v1.1.5
  • index.html, 用来展现游戏的公文
  • main.js, 大家写代码的地方
  • asset/, 用来保存小鸟和管仲的图形的文书夹(bird.png和pipe.png)

用浏览器张开index.html,用文件编辑器展开main.js

在main.js中能够见见我们前边提到的Phaser工程的大旨结构

JavaScript

// Initialize Phaser, and creates a 400x490px game var game = new
Phaser.Game(400, 490, Phaser.AUTO, 'game_div'); // Creates
a new 'main' state that will contain the game var
main_state = { preload: function() { // Function called first to load
all the assets }, create: function() { // Fuction called after
'preload' to setup the game }, update: function() { //
Function called 60 times per second }, }; // Add and start the
'main' state to start the game
game.state.add('main', main_state);
game.state.start('main');

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Initialize Phaser, and creates a 400x490px game
var game = new Phaser.Game(400, 490, Phaser.AUTO, &#039;game_div&#039;);
 
// Creates a new &#039;main&#039; state that will contain the game
var main_state = {
 
    preload: function() {
        // Function called first to load all the assets
    },
 
    create: function() {
        // Fuction called after &#039;preload&#039; to setup the game    
    },
 
    update: function() {
        // Function called 60 times per second
    },
};
 
// Add and start the &#039;main&#039; state to start the game
game.state.add(&#039;main&#039;, main_state);  
game.state.start(&#039;main&#039;);

接下去大家一回到位preload(),create()和update()方法,并扩张部分新的点子。

1)组合继承

function Mother (age) { this.age = age; this.hobby =
[‘running’,’football’] } Mother.prototype.showAge = function () {
console.log(this.age); }; function Person (name, age) {
Mother.call(this, age);  //第一遍推行 this.name = name; }
Person.prototype = new Mother();  //第三遍实行Person.prototype.constructor = Person; Person.prototype.showName =
function () { console.log(this.name); } var p1 = new Person(‘杰克’, 20);
p1.hobby.push(‘basketball’); //p1:’杰克’;
__proto__:20,[‘running’,’football’] var p2 = new Person(‘Mark’,
18); //p2:’Mark’; __proto__:18,[‘running’,’football’]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Mother (age) {
    this.age = age;
    this.hobby = [‘running’,’football’]
}
Mother.prototype.showAge = function () {
    console.log(this.age);
};
 
function Person (name, age) {
    Mother.call(this, age);  //第二次执行
    this.name = name;
}
Person.prototype = new Mother();  //第一次执行
Person.prototype.constructor = Person;
Person.prototype.showName = function () {
    console.log(this.name);
}
 
var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’);  //p1:’Jack’; __proto__:20,[‘running’,’football’]
var p2 = new Person(‘Mark’, 18);  //p2:’Mark’; __proto__:18,[‘running’,’football’]

结果是酱紫的:

银河国际网址手机版 15  银河国际网址手机版 16

此处首先次进行的时候,获得 Person.prototype.age =
undefined, Person.prototype.hobby =
[‘running’,’football’],第2回施行也正是 var p1 = new Person(‘杰克’,
20) 的时候,得到 p1.age =20, p1.hobby =
[‘running’,’football’],push后就改为了 p1.hobby =
[‘running’,’football’, ‘basketball’]。其实分辨好 this
的变化,领悟起来也是比较轻巧的,把 this 轻松替换一下就能够获取这么些结果了。
假诺认为通晓起来相比绕的话,试着把脑筋里面包车型地铁概念扔掉啊,把温馨当浏览器从上到下实践一次代码,结果是否就出去了呢?

由此第二回实行原型的构造函数
Mother(),我们在对象实例中复制了一份原型的习性,那样就完了了与原型属性的送别独立。留意的你会发觉,大家先是次调用
Mother(),好像什么用都并未有啊,能不调用他呢?能够,就有了下边包车型客车寄生组合式承继。

鸟类的创设

我们先来看如何增添贰个用空格键来支配的小鸟。

第一大家来更新preload(),create()和update()方法。

JavaScript

preload: function() { // Change the background color of the game
this.game.stage.backgroundColor = '#71c5cf'; // Load the
bird sprite this.game.load.image('bird',
'assets/bird.png'); }, create: function() { // Display the
bird on the screen this.bird = this.game.add.sprite(100, 245,
'bird'); // Add gravity to the bird to make it fall
this.bird.body.gravity.y = 1000; // Call the 'jump' function
when the spacekey is hit var space_key =
this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this); }, update: function() { // If
the bird is out of the world (too high or too low), call the
'restart_game' function if (this.bird.inWorld == false)
this.restart_game(); },

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
preload: function() {  
    // Change the background color of the game
    this.game.stage.backgroundColor = &#039;#71c5cf&#039;;
 
    // Load the bird sprite
    this.game.load.image(&#039;bird&#039;, &#039;assets/bird.png&#039;);
},
 
create: function() {  
    // Display the bird on the screen
    this.bird = this.game.add.sprite(100, 245, &#039;bird&#039;);
 
    // Add gravity to the bird to make it fall
    this.bird.body.gravity.y = 1000;  
 
    // Call the &#039;jump&#039; function when the spacekey is hit
    var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
    space_key.onDown.add(this.jump, this);    
},
 
update: function() {  
    // If the bird is out of the world (too high or too low), call the &#039;restart_game&#039; function
    if (this.bird.inWorld == false)
        this.restart_game();
},

在那八个艺术上边,大家再增添三个新的格局。

JavaScript

// Make the bird jump jump: function() { // Add a vertical velocity to
the bird this.bird.body.velocity.y = -350; }, // Restart the game
restart_game: function() { // Start the 'main' state, which
restarts the game this.game.state.start('main'); },

1
2
3
4
5
6
7
8
9
10
11
// Make the bird jump
jump: function() {  
    // Add a vertical velocity to the bird
    this.bird.body.velocity.y = -350;
},
 
// Restart the game
restart_game: function() {  
    // Start the &#039;main&#039; state, which restarts the game
    this.game.state.start(&#039;main&#039;);
},

封存main.js并刷新index.html后您就能够收获贰个用空格键来调控的鸟儿了。

2)寄生组合式承继

function object(o){ function F(){} F.prototype = o; return new F(); }
function inheritPrototype(Person, Mother){ var prototype =
object(Mother.prototype); prototype.constructor = Person;
Person.prototype = prototype; } function Mother (age) { this.age = age;
this.hobby = [‘running’,’football’] } Mother.prototype.showAge =
function () { console.log(this.age); }; function Person (name, age) {
Mother.call(this, age); this.name = name; } inheritPrototype(Person,
Mother); Person.prototype.showName = function () {
console.log(this.name); } var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’);//p1:’Jack’;
__proto__:20,[‘running’,’football’] var p2 = new Person(‘Mark’,
18); //p2:’Mark’; __proto__:18,[‘running’,’football’]

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
function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}
 
function inheritPrototype(Person, Mother){
    var prototype = object(Mother.prototype);
    prototype.constructor = Person;    
    Person.prototype = prototype;    
}
                        
function Mother (age) {
    this.age = age;
    this.hobby = [‘running’,’football’]
}
Mother.prototype.showAge = function () {
    console.log(this.age);
};
 
function Person (name, age) {
    Mother.call(this, age);
    this.name = name;
}
 
inheritPrototype(Person, Mother);
 
Person.prototype.showName = function () {
    console.log(this.name);
}
 
var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’);//p1:’Jack’; __proto__:20,[‘running’,’football’]
var p2 = new Person(‘Mark’, 18); //p2:’Mark’; __proto__:18,[‘running’,’football’]

结果是酱紫的:

银河国际网址手机版 17 银河国际网址手机版 18

原型中不再有 age 和 hobby 属性了,只有七个法子,就是大家想要的结果!

关键点在于 object(o) 里面,这里借用了三个临时对象来都行制止了调用new
Mother(),然后将原型为 o
的新指标实例再次来到,进而产生了原型链的安装。很绕,对吧,那是因为我们不能一直设置
Person.prototype = Mother.prototype 啊。

标签:,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图