17年1月开发小记

1.在向SVG中添加新的元素时,需要手动的使用createElementNS方法,如果直接使用jquery里面的方法添加的话,他是不会显现出来的;

2.有些元素是无法通过append方法添加的,比如<head>中的meta标签没有办法通过jquery动态添加,但是可以通过attr设置它的属性;

3.使用fetch进行跨域资源获取时,只需要极简单的将mode设置为no-cors就可以了;

4.自己强行郁闷了很久,想要在一个组件中同时使用redux的全局store和组件自身的state,这样会发出警告;如果有不同需要的话还是就简单的使用setState吧,可以用在只是有简单交互性并且页面上可能出现多次的组件上;

5.fetch的跨域虽然可以通过no-cors实现,但是返回的promise却是一个空的对象,里面的数据没有任何用处;

6.http://www.bilibili.com/index/catalogy/1-3day.json 不知道怎么取得这个地址的资源

7.在使用ES6时,千万不要手贱使用一些全局变量名字定义输出的对象或者其他数据,这样他不会是局部的,而是直接将其替换掉了,比如:

1
export default JSON = {a:1}

这样会将全局的JSON对象替换为{a:1};

8.async/await 是非常新的 API,属于 ES7,目前尚在 Stage 1(提议) 阶段,这是它的完整规范。使用 Babel 开启 runtime 模式后可以把 async/await 无痛编译成 ES5 代码。也可以直接使用 regenerator 来编译到 ES5。

9.不要把一个有CSS动画的元素,甚至是通过绝对定位的SVG元素放到一个有图片背景的元素里面,这样会非常损耗性能,在手机上尤其突出;

10.【实在太坑了】对于一些组件千万不要忘记将本身的事件屏蔽掉,checkbox这种东西点击一次的话,也会触发两次操作;

11.H5开发最好的是在less中使用rem做单位,而在js中使用获取屏幕分辨率的函数计算长度或高度

12.按照普通设计,当网站cookie信息有1 KB、网站首页共150个资源时,用户在请求过程中需要发送150 KB的cookie信息,在512 Kbps的常见上行带宽下,需要长达3秒左右才能全部发送完毕。 尽管这个过程可以和页面下载不同资源的时间并发,但毕竟对速度造成了影响。 而且这些信息在js/css/images/flash等静态资源上,几乎是没有任何必要的。 解决方案是启用和主站不同的域名来放置静态资源,也就是cookie free。

13.将css放置在页面最上方应该是很自然的习惯,但第一个css内引入的图片下载是有可能堵塞后续的其他js的下载的。而在目前普遍过百的整页请求数的前提下,浏览器提供的仅仅数个并发,对于进行了良好优化甚至是前面有CDN的系统而言,是极大的性能瓶颈。 这也就衍生了domain hash技术来使用多个域名加大并发量(因为浏览器是基于domain的并发控制,而不是page),不过过多的散布会导致DNS解析上付出额外的代价,所以一般也是控制在2-4之间。 这里常见的一个性能小坑是没有机制去确保URL的哈希一致性(即同一个静态资源应该被哈希到同一个域名下),而导致资源被多次下载。

14.我们可以使用<audio>元素流式加载音乐文件, 在JavaScript中调用createMediaElementSource方式, 直接操作HTMLMediaElement, 像play()pause()的方法均可调用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
context = new AudioContext();
/* 声明我们的 MediaElementAudioSourceNode 变量 */
var sound,
/* 新建一个 `<audio>` 元素. Chrome 支持通过 `new Audio()` 创建,
* Firefox 需要通过 `createElement` 方法创建. */
audio = new Audio();

/* 添加 `canplay` 事件侦听当文件可以被播放时. */
audio.addEventListener('canplay', function() {
/* 现在这个文件可以 `canplay` 了, 从 `<audio>` 元素创建一个
* MediaElementAudioSourceNode(媒体元素音频源结点) . */
sound = context.createMediaElementSource(audio);
/* 将 MediaElementAudioSourceNode 与 AudioContext 关联 */
sound.connect(context.destination);
/*通过我们可以 `play` `<audio>` 元素了 */
audio.play();
});
audio.src = '/path/to/audio.mp3';

15.window.performance中有一些函数可以准确的测量时间,比在执行程序前后使用console.log更加准确,此外chrome还支持memory属性显示现在浏览器使用的内存(堆内存)

16.在新的audio-context接口中使用的有关于时间的接口,比一般使用的date更加精确,可以做到准确调音的水准;

17.在处理声音的时候,如果需要延迟改变一些变量,不要使用setTimeout
毫秒级别的控制并不够精确,JS主线程中有其他高优先级的任务要进行,页面布局,垃圾回收以及事件循环中的回调函数,并且其发生时间还会被当前页面是否在后台所影响,如果是后台程序会比前台发生的更加慢;取而代之的是setValueAtTime这个函数

18.将声音升高一个半音程(十二分之一个八音度)

1
2
3
4
5
6
function playNote(semitones) {
// Assume a new source was created from a buffer.
var semitoneRatio = Math.pow(2, 1/12);
source.playbackRate.value = Math.pow(semitoneRatio, semitones);
source.start(0);
}

19.八度之间的频率是两倍的关系,比如A2的频率就是A3的两倍;根据上面一个计算出来的每个半音程之间的倍数是1.0595左右

20.The indexes of the output can be mapped linearly between zero and the nyquist frequency
按照频域取出来的索引其实是0到奈奎斯特采样频率之间的值

21.document上的webkitvisibilitychange事件在当前页面进入前台或进入后台时触发,通过检查document.webkitHidden可以判断

22.如果想要调试canvas元素或者webGL,在chrome://flags页面中把实验性的chrome开发工具打开,重新启动后在设置里面即可打开canvas profile对绘画元素进行调试(旧版本)

23.nginx如果重新配置后使用nginx -s reload发现没有变化,需要nginx -s stop停止后在重新开启

24.有些页面可能有反爬虫措施,通过后台直接请求不对头进行包装的话会给你返回一顿根本无法解析的乱码(http://www.bilibili.com/index/catalogy/13-3day.json)

25.浏览器的全屏显示事件必须交给点击事件触发(怎么判断我是点击事件触发的??)

26.es6没有静态变量的说法,如果要定义常量可以用如下方式:

1
2
3
4
5
6
7
8
class Agent {
static get CIRCLE() {
return 1;
}
static get SQUARE() {
return 2;
}
}

Agent.CIRCLE即为1,同理我们可以把一个对象return回去,里面全部包含着常量;

27.vertical-align属性只对有valign属性的元素起作用,比如tdthcaption等,对spandiv没有用;

28.如何import一个文件中的所有图片?就像这样

1
2
let requireContext = require.context("../assets/image/",true,/^\.\/.*\.gif$/)
const images = requireContext.keys().map(requireContext)

29.假如有以下ES6代码:

1
2
3
4
5
arr1 = [1,0]
arr2 = [0,1]
arr3.push(arr1,arr2)
arr1.length = 0
arr2.length = 0

因为是对象的引用,最后得到的只是一个空的数组
解决办法:

1
arr3.push([...arr1],[...arr2])

30.以下总结自google开发者中心文档:
$_ 可以获取到上一个表达式计算出来的值
$0 测试的时候还在通过dom操作选择节点?不行的哈,直接通过这个拿到控制台里选定的元素
$$$ 在没有引入jquery等的时候,前一个选择单个DOM后一个选择出一个数组

31.在用canvas做东西的时候一定要想清楚是不是只有一个或者两个图层,如果出现遮盖的情况就必须要用双canvas或者清空整个画布了,而且小范围清除重绘反而会增加渲染开销

十月开发小记

Node Part

1.在程序中通过process.env.npm_lifecycle_event这个变量,可以获得npm run ${XXX}之中的字符串,针对不同的操作做不同的配置

2.0.0.0.0这个IP在windows下可以代表所有没有被标记的ip,具体用途可以是在使用服务器时,将访问端口配置成0.0.0.0,这样就可以在外网对本机服务器进行访问了

3.process.argv数组之中存储的是实际运行的命令 每个执行的js文件保存的字符串都会是完整的路径

4.呵呵react-router居然默认安装的是0.13.0版本,这真是极大的一个坑,值得你调试一天

5.Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

6.document.documentElement.clientWidth;,document.documentElement.clientHeight;可以获取移动设备的可见高度和宽度,移动端是个大坑,在微信和UC浏览器中显示可能都会有巨大不同;

System Part

1.进程间的内存是无法共享的,线程的内存共享,对一个应用程序开辟多个线程便可以”同时”进行多种操作

2.每个线程都一个自己的帧,帧里面存放了现在的堆栈信息和过程信息;帧里面的信息不会不会混杂到一起

React Native Part

1.运行packager的时候,经常会出现各种各样的问题,在windows上更是坑洞遍地,除了教程里面经常出现的之外,这里再说你两个

如果程序一直卡在find dependencies的状态,并且内存不断攀高,到了一定时间过后告诉你内存达到最大值并推出,不要想太多,这只是因为你没有把包装好,不要使用cnpm装包,而且也一定要注意过程中出现的gyp错误,这个错误的出现是因为,各种包为了适应不同的平台(*inux,windows),选择在npm install过后再进行编译,如果没有编译成功就会抛出错误,为日后开发错误埋下伏笔;

如果报了watchman的错误,可能是因为你没有装全局的watchman也有可能是因为你装了cygwin导致系统认为任务是在linux环境下进行,这个时候需要去掉cygwin环境变量;当然还有可能是因为你是windows系统,他有几率报错,这个时候要删掉文件里面的watchmannpm uninstall warchman

2.react-native中的阴影属性仅支持ios系统,安卓只有靠图片来实现了

3.如果需要使用POST发送表单请求,最好是直接用下面这种方式,使用FormData对象传数据的话,会被webkit浏览器强行转换为webkit的一种binary文件,后台容易报400的参数错误;

1
2
3
4
5
6
7
8
fetch("http://bilibili-service.daoapp.io/search",{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: "content=aa&page=0&count=20"
}).then(rsp => rsp.json())
.then(rsp => console.info(rsp))

nginx配置文件中文解析

转载,忘记了出处

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#定义Nginx运行的用户和用户组
user www www;

#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;

#进程文件
pid /var/run/nginx.pid;

#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;

#工作模式与连接数上限
events
{
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
use epoll;
#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 65535;
}

#设定http服务器
http
{
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型
#charset utf-8; #默认编码
server_names_hash_bucket_size 128; #服务器名字的hash表大小
client_header_buffer_size 32k; #上传文件大小限制
large_client_header_buffers 4 64k; #设定请求缓
client_max_body_size 8m; #设定请求缓
sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on; #防止网络阻塞
tcp_nodelay on; #防止网络阻塞
keepalive_timeout 120; #长连接超时时间,单位是秒

#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

#gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用

upstream blog.ha97.com
{
#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
server 192.168.80.121:80 weight=3;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}

#虚拟主机的配置
server
{
#监听端口
listen 80;
#域名可以有多个,用空格隔开
server_name www.ha97.com ha97.com;
index index.html index.htm index.php;
root /data/www/ha97;
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
#图片缓存时间设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*\.(js|css)?$
{
expires 1h;
}
#日志格式设定
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
#定义本虚拟主机的访问日志
access_log /var/log/nginx/ha97access.log access;

#对 "/" 启用反向代理
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host;
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
}

#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
}

#本地动静分离反向代理配置
#所有jsp的页面均交由tomcat或resin处理
location ~ .(jsp|jspx|do)?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}

#所有静态文件由nginx直接读取不经过tomcat或resin
location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
{
expires 15d;
}
location ~ .*.(js|css)?$
{
expires 1h;
}
}
}

node文档阅读笔记

node & server:

1.module还有些其他属性,简单说下吧。
module.id 模块id,往往是模块路径
module.children 子模块
module.filename 模块路径
module.loaded 是否加载完毕
module.parent 父模块
module.paths 各级 node_modules 目录路径

2.require.resolve 不会加载执行,只会返回模块的绝对路径。
require.cache 缓存所有已经加载的模块,如果你要更新模块就要删除这里的缓存。

1
2
3
var a = require('./a');
var p = require.resolve('./a'); // 得到模块路径
delete require.cache[p]; // 删除模块缓存

3.require.extensions 自定义模块后缀,可以手动设置模块的加载,比如说直接在测试的时候拒绝加载某些类型的文件只需:
运行如下语句时,css文件便不会读取(已过时)

1
2
3
require.extensions['.css'] = function noop() {
return null;
}

4.process模块用来与当前进程互动,可以通过全局变量process访问,不必使用require命令加载。它是一个EventEmitter对象的实例

5.console 函数默认情况下都是异步执行的,除非要将信息输出到文件中。硬盘已经很快了,操作系统通常使用高速缓存进行读写,但仍然不可避免发生进程阻塞的情况。

6.最简单的调用栈调试可以直接使用console.trace() 打印出调用处的调试信息

7.内存的指向和克隆(数组

1
2
3
4
5
6
const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000;

const buf1 = Buffer.from(arr); // copies the buffer
const buf2 = Buffer.from(arr.buffer); // shares the memory with arr;

8.for...in是ES5里的遍历键 for...of是ES6的遍历值

9.Buffer.byteLength(string[, encoding])返回字符串的实际字节长度。与 String.prototype.length 不同的是,该方法返回数值表示字符串占多少字节,而 String.prototype.length 返回的数值表示字符串有多少个字符。通过这个我们可以计算出一个字符串里有多少汉字符或其他字符(只包含一种其他字符

10.child_process.spawn() 方法用于异步创建子进程,不会阻塞 Node.js 的事件循环机制。
child_process.spawnSync() 方法与上一个方法提供了相同的功能,不同之处在于它是同步执行的,执行时会阻塞事件循环机制,知道子进程结束任务并退出。

11.疑惑??????每新创建一个EventEmmiter的实例接相当于新开了一个消息队列吗?????

12.当 EventEmitter 的实例出现错误时,就会触发 error 事件,这在 Node.js 中被视为一个特殊事件。
为了避免 Node.js 的进程崩溃,开发者可以使用 domain 模块(不过该模块已被抛弃)或者注册一个 process.on('uncaughtException') 来解决:

1
2
3
process.on('uncaughtException', (err) => {
console.log('whoops! there was an error');
});

13.默认情况下,任何事件可以注册 10 个监听器。EventEmitter 的实例可以通过 emitter.setMaxListeners(n) 方法修改这一限制值。如果要为所有的 EventEmitte 实例修改该属性,需要使用 EventEmitter.defaultMaxListeners 属性。

14.如果未对 response 事件设置处理函数,则响应信息就会被忽略。不过,如果添加了 response 事件的处理函数,则无论是使用 response.read(),或者添加 data 事件处理器,还是调用 .resume() 方法,都必须对响应对象的数据进行处理。只有数据经过处理之后,才会触发 end 事件。此外,除非读取数据,否则将会占用不必要的内容,直至触发 process out of memory 错误。

15.使用 response.setHeader() 配置头信息之后,这些头信息会被其他头信息合并并传递给 response.writeHead(),但是传递给 response.writeHead() 的头信息优先级较高,这就相当于你可以使用setHeader设置多个头信息不断叠加,但是要在响应发送过后再使用setHeader的话将会报错

16.在 HTTPS 中,使用 request.socket.getPeerCertificate() 方法可以获取客户端的验证资料。

17.require引入的模块实际上是通过在文件的外面包上一个:

1
2
3
(function(require,module,export....){
....{content}....
})()

做到的,所以不要再问require是哪里来的了

18.require.main既是主文件模块,并且如果没能够在自己的文件夹中找到需要的模块的话,会到NODE_PATH所指定的环境变量中去找有没有node_modules

19.os模块可以用来判断系统,并针对不同的系统进行相应的配置,比如在使用child_process创建子线程的过程中,我们就需要知道是window或者*nix,看是来使用bat还是shell;

20.path.join([path1][, path2][, ...])方法非常实用,可以拼接出一个路径,空字符会被视为.,即当前路径

1
2
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// returns '/foo/bar/baz/asdf'

21.当向进程发送SIGNUP信号的时候,将会关闭该进程;(应用:如果我们可以忽略SIGHUP信号,关掉窗口应该就不会影响程序的运行了。nohup命令可以达到这个目的,如果程序的标准输出/标准错误是终端,nohup默认将其重定向到nohup.out文件。值得注意的是nohup命令只是使得程序忽略SIGHUP信号,还需要使用标记&把它放在后台运行,这样在退出session后也可以保持程序运行了)

进行项目开发时做的一些小笔记

校园说(Campussay)项目中遇到的问题

1.scriptonload事件是在script引入的内容执行完成后再触发的。

2.如果一个变量在函数里面使用了两次以上的话,最好将他转变为局部变量,这样可以更快的读取到,提高性能

3.chrome有一些非常牛逼的特性,比如说光标在一个连接上放一段时间后台会预处理连接。

4.SSE是单向的,由服务器向客户端推送消息的一个东西,而且只能推送文本,不过在传输过程中可以动态使用gzip压缩,并且不用做过多的配置,比websocket轻量很多。

5.window.onbeforeunload事件会在刷新窗口,关闭窗口之前进行,如果在回调函数中return一个非空值的话,则这个值将转化为字符串显示在框中询问用户是否需要关闭当前窗口。

6.data属性无法通过大写获取到,比如设置属性offSet,如果使用jQuery的话只能用$().data("off-set")才能得到值,并且值得注意的是,jquery里面有时候通过data方法获取到的是第一次调用data方法时的值;最好还是使用attr获取;

7.jquery里面的on方法如果执行多次的话,他的回调函数也会执行多次,如果要想解决这个问题可以先off了再on

React-Native中遇到的问题

20.尝试了很多方法,最后才发现react-nativescrollview中使用的onScroll回调方法里面有evt的回调参数,回调参数里面有一个值藏得很深,就是evt.nativeEvent.contentOffset.y,这个值可以拿给我们看当前scrollview是否滚到了顶部或者是底部。(之前是不是傻,对着返回的对象看了半天都没有找到这个属性)

21.关于React中的通信方法,一般来说,使用props是效率最高的,不过这是仅限于从父级元素传参数给子级元素,如果要想子级元素传值给父级元素的话就需要父元素传递一个回调函数给子元素执行。在一些距离较远的并且信息传输速度要求不高的通信中,可以使用RCTDeviceEventEmitter这个类进行事件类型的通信

22.不要指望使用特textInput的属性来获取输入框的值,那玩意儿只能用来强制设定文本框的value,你只能通过change事件把其中的值存起来,真是太IMBA了!

23.在使用Reducer的时候千万不要改变原先的state,比如poppush这种方法都不要用,用了没有效果;他会自己比较你的state有没有改变,刷新判断成功之后才会刷新

24.在ES6中,class就相当于是JAVA中的Class了,他的静态方法要用static关键字标示,并且不能使用箭头函数的形式,且调用此函数的时候不是使用this,而是使用类名。

25.那天看到说在ES6中没有静态变量,但是我试验出来是有的,不知道怎么回事

26.class里面如果想要用属性的方法写函数,并且能够通过this调用的话,必须要通过在constructor中进行bind,更简单的方法就是直接使用箭头函数了,箭头函数会将this指针绑定在他定义的地方;

27.今天看到0.31版本更新里写的zIndex属性可以生效了,大家就欢呼把;

28.Fetch 请求默认是不带 cookie 的,需要设置fetch(url, {credentials: 'include'})

29.服务器返回 400,500错误码时并不会reject,只有网络错误这些导致请求不能完成时,fetch才会被 reject