这次,我们的目标是开发一个网页版猜拳小游戏。首先看看最终的效果图:
瞄一眼效果图,游戏玩法大致可以了解个七七八八了。很简单,用户从石头剪刀布中随便选一个并出拳后,电脑也会随机(实际上是根据服务端的返回值)做出选择,之后判断用户和点小融之间的胜负,弹出相应的动画即可。
游戏的玩法虽然简单,但实际的开发过程中,坑还是不少。下面我们从头梳理一下开发的过程。
开发过程中,我们一般都会在webpack的配置文件中添加热更新的插件:
1 |
|
有了这个插件,开发过程中,一旦我们对代码进行了改动,webpack会立即rebuild我们的代码,大大提高了开发效率。那么,它背后的原理是什么呢?
Keywords:
TC39, tokens, lexical grammer, terminal symbols, parse tree, nonterminal,
Production, terminal symbols, nonterminal symbols
最近抽空大致看了下ES2018的specification,内容深广,涉及的语言设计的底层细节非一日所能达。面对这样庞大的一份资料,如何看待它呢?我的态度是,不求通读标准,但求拥有阅读和理解标准的能力。即使你熟记标准中的所有细节,对应用开发者来说,也无助于解决实际生产中的绝大部分问题,但当我们遇到某些无法可解疑难杂症时,查阅标准,可能是我们攻克问题的最后一件武器。更重要的是,对于自己朝夕使用的工具,如果都只知皮毛,那也确实说不过去了。
对于前端开发,js的事件系统可以说是我们接触最多的特性之一,甚至很多人把他当作了js与生俱来的特性,把js看作一门基于事件驱动的语言。
但当我们追本朔源,我们会发现,这个看似高深的特性又是一个基于发布/订阅模式的经典实现。下面,我们就仿照nodejs中的这一模块,一步步实现一个基本的事件发布系统。
使用onclick添加的事件为dom0事件,同一个元素只能拥有一个dom0事件,后添加的事件会覆盖之前的事件。
1 |
|
对dom0事件,IE的事件流是冒泡(首先出发叶子节点事件),而netscape采用的是事件捕获(相反的顺序)。
Javascript中的this
一直是一个老大难的问题,在ES6中,箭头函数的1
2
3
<!--more-->
### ES5中的```this
首先需要明确this
绑定的基本原则:this
绑定发生在函数的调用时(而非声明时),也就是所谓的运行时绑定。明确了这一点,我们可以看看实际使用中this
常常遇到的几种情况:
1 |
|
根据我们上面的原则,函数foo调用时未执行任何绑定操作,this默认指向全局对象,也就是a。需要注意的是,若我们采用1
2
#### 2. 对象中的隐式绑定
function foo() {
console.log(this.a);
}
var b = {
a: 2,
foo: foo
}
b.foo(); //2
var c = {
a: 3,
b: b
}
c.b.foo(); //2
1 |
|
function foo() {
console.log(this.a);
}
var obj = {
a: 2
}
foo.call(obj); // 2
foo.apply(obj); // 2
1 |
|
function foo() {
console.log(this.a);
}
var obj = {
a: 5
};
var obj2 = {
a: 10
};
var bar = foo.bind(obj);
bar(); // 5
bar.apply(obj2); // 5
1 |
|
function foo(a) {
this.a = a;
}
var obj = {
a: 5
};
var baz = foo.bind(obj); // 绑定obj
var bar = new baz(2); // new覆盖了绑定
console.log(bar.a); // 2
1 |
|
function foo() {
console.log(this.a);
}
var obj = {
a: 5,
foo: foo
}
setTimeout(obj.foo, 10); // undefined
1 |
|
setTimeout(function() {
console.log(this.a);
}, 10);
1 |
|
setTimeout(obj.foo.bind(obj), 10); // 5
1 |
|
为了解决绑定丢失的问题,ES6中的箭头函数对this
绑定做了一定的改进,具体来说,就是:箭头函数内的this
始终指向调用它的闭包所绑定的this
。说起来有点拗口,下面还是用setTimeout的例子来解释这句话:
1 |
|
setTimeout对应的闭包是foo(注意js中,闭包只针对函数,Object不是闭包),而foo的this
对应obj,因此setTimeout中,匿名箭头函数的this
指向调用它的闭包(也就是foo函数)对应的this
。可以看到,箭头函数完美解决了匿名函数this绑定丢失的问题。
参考: