@FunC
2017-08-10T08:54:12.000000Z
字数 8334
阅读 2083
前端
不用循环创建下标和索引相同的数组(注意本来数组的键就是数字,遍历键名)
//ES5
//apply的第二个参数是类数组,所以这里的{length: 100}会识别成一百项undefined的数组
//Object.keys()返回对象属性字符串组成的数组,而数组的属性就是下标
Object.keys(Array.apply(null, {length: 100}));
//ES6
//array.keys()是一个迭代器,value等于下标,用扩展运算符展开就是下标组成的数组了
[...Array(100).keys()]
onresize 事件会在窗口或框架(iframe)被调整大小时发生。除了window对象和body元素,其它元素虽然有的支持,但不会主动触发
resize的使用方式:
- 直接在元素中定义属性
- 直接给onresize赋值(强制,入侵式事件注册)
可以给window和document.body的onresize赋值
如window.onresize=function(){},document.body.onresize=function(){}
但需要注意的是,赋值之后,window.onresize === document.body.onresize 为true- 使用事件监听(事件队列,一个元素同一事件可以绑定多次)
只对window有作用
如window.addEventListener(“resize”,fn);
if(window.PointerEvent) //IE 11 & Edge
{
$('#holder').on('pointermove', printcoordinate);
}
else if(window.MSPointerEvent) //IE10
{
$('#holder').on('MSPointerMove', printcoordinate);
}
else //Chrome, Safari
{
$('#holder').on('touchmove', printcoordinate);
}
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
<meta name="viewport" content="width=device-width">
//最佳方案(缺点是兼容性差)
.rect{
width:100vmin;//vmin为1%视窗宽高中较小的一个
heigth:100vmin;
}
//利用padding、margin的百分值计算依赖于父元素的width,无法实现横屏时的自适应
.rect{
width: 100%;
background-color: lightblue;
}
.rect:after{
display: block;
content:' ';
padding-top:100%;
}
//一个元素既是第一个也是倒数第四个=>只有四个子元素
//这时的相邻兄弟元素就是2,3,4
//再加上自己=>仅有4个子元素时选择全部子元素
.li:first-child:nth-last-child(4),
.li:first-child:nth-last-child(4) ~ li {
// 假设需求是近当有4个li时为四宫格
padding-top: 50%;
width: 50%;
}
//a标签之间会有无法点击的空白,这是由于换行符导致的(不换行或不闭合
//可在nav设置font-size:0;或者改用flex
<nav>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
基于baseline,可让父元素font-size:0;或极小的line-height;或使用flex
为什么用let就能解决?
原本用var,循环体属于全局作用域,i也在全局作用域内。
当计时器到达后,开始寻找变量
使用var时,顺序是:事件绑定函数作用域→上一级作用域→...→全局作用域
当使用let时,使循环体形成了块级作用域,即每一个循环体都是不同的作用域
顺序是:事件绑定函数作用域→循环体作用域→上一级作用域→...→全局作用域
相当于
{
let i = 1;
setTimeout(() => console.log(i)}, i*1000);
}
{
let i = 2;
setTimeout(() => console.log(i)}, i*1000);
}
{
let i = 3;
setTimeout(() => console.log(i)}, i*1000);
}
从垃圾清理角度讲,当当前作用域结束后,会尝试清理不再被引用的变量。
使用var时,循环体为全局作用域,全局作用域在关闭环境时才清除。
而使用let时,循环体为块级作用域,每次循环都要尝试清除不再被引用的变量,而这时i被setTimeout的console.log引用着,所以形成了闭包(?)
传统的使用闭包(立即执行函数传参数)的解决方案其实就是在模拟块级作用域。update: ES6中的let在循环中的行为进行了特别规定
所以其实内部完成了赋值:
for (let i = 0; i < 10; i++) {
let j = i; // 实际上内部多了这一步
console.log(j);
}
基于buffer实现,继承自EventEmitter
自动控制后端压力,可以链式调用,方便
如fs.readFile('./sthBig.gz', callback)
需要将整个文件读入内存,才能返回结果(大量请求时消耗巨大)
改成fs.createReadStream('./sthBig.gz')
,每次读一个chunk,中间还能处理(如使用split()模块调整为每chunk一行)需要加工时可使用transfromliu(如through2模块),读写完后的回调可以通过监听'close'事件来触发。
readstream,只可读(但在消耗前可通过readstream.push(sth)写入缓存)
writestream,只可写,还能通过.write()/.end()(不再可以写入)来写入
transfrom,可读可写,但不存数据。中转,中间处理(如a.pipe(b).pipe(c))中的b
duplex,可读可写存数据,如a.pipe(b).pipe(a)中的a。
HTML文档能流式处理 -> 所以其实document也有.open(), .write(), .close()方法
在文档解析中途进行.write():附加在文档尾部
文档加载结束后, 调用了.close()关闭文档流
此后再次调用.write(), 则强行先执行一次.open(),即开启新的文档流-> 故此后再write()会覆盖页面内容
application/x-www-form-urlencoded
multipart/form-data
text/plain
以外的主体内容时,会使用OPTIONS发送Preflight请求 Origin
Access-Control-Request-Method
Access-Control-Request-Headers(可选,自定义头部)
。响应头对应Access-Control-Allow-Origin
Access-Control-Allow-Method
Access-Control-Allow-Headers
Access-Control-Max-Age
float失效:
1.position:absolute/fixed;
2.display:flex
.parent{
display:flex;
justify-contet: center;
align-items: center;
}
.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%)//自身的50%
}
.parent{
display: table-cell;
text-align:center;
vertical-align:middle;
}
.child{
display: inline-block;
vertical-align: center;
}
git remote add origin xxxxxxxx
//首次要用-u push上去同时关联文件
git push -u origin master
git push origin master
//克隆远程库
git clone xxxxxx
'A' !== new String('A'); //true
new String('A') !== new String('A'); //true
简单总结就是:
1. 非数字下标会忽略
2. length可写
var arr = [];
arr['a'] = 'a';
console.log(arr.length);//0
arr['2'] = 2;
console.log(arr.length);//3
arr.length = 0;
console.log(arr.length);//0
arr.length = 3;
console.log(arr);//[undefined,undefined,undefined]
思路:将浮点数转换为整数,计算后再切换为小数。
1. 用 split('.');判断小数点位数n
2. 取位数最大的,分别乘10的n次方
3. 重点:对结果使用parseInt(),转换为真正的整数
4. 整数运算,再除以10的n次方
//宽高
element.offsetHeight
element.offsetWidth
//绝对位置
element.offsetTop
element.offsetLeft
//相对位置
var rectObj = element.getBoundingClientRect();
//只读
rectObj.left
rectObj.top
rectObj.right
rectObj.bottom
rectObj.height//IE8及以下没有宽高
rectObj.width
伪造用户的请求,如让用户访问钓鱼网站,网站向目标站点发起请求,此时会带上用户的cookie使验证通过
cookie分为:session cookie(临时cookie)、本地cookie(expire之后才失效)(部分标签的请求禁止携带本地cookie,如img、iframe、script、link)CSRF的防御:
1. 验证码(需要用户互动才能完成操作,但仍有可能被钓鱼。且不可能全部请求都加验证码)
2. referer过滤:过滤不合理的referer(但服务端不一定能取到referer,有时出于隐私考虑会闲置referer的发送)
3. 依赖AJAX的CORS配合JSON API:因为AJAX限制跨域,而能跨域的form标签不能发送JSON
4.CSRF token:(从本质出发)CSRF本质:重要操作的所有参数能被猜到(才能构建出请求)
请求中带上随机数token
token由服务端发给客户端,请求时需要带上token进行验证token注意事项:
- 放在表单的隐藏项中,敏感操作改为post
- 避免token出现在**页面的**URL中,此时可能通过referer被记录
- token不能被ajax获取到(不要提供/csrf路由)
- token只能避免CSRF,如果攻击者能使用JavaScript(如XSS攻击),token自然无效
可能输出位置
1. HTML标签中<div>$var</div>
构造script标签或使用事件属性等
2. HTML属性中,使用引号闭合属性
3. CSS中输出:含url()
的属性,配合JavaScript、dataURI等伪协议等
4. 对于富文本:使用白名单
(set-cookie: key=value; expirse: GMT time; max-age:xxxs; domain: path: secure;等)
cookie储存于客户端,session储存于服务端。
cookie是客户端的状态保持方案(HTTP协议无状态)
session是客户端与服务端状态保持的解决方案(如购物车的添加),需要依赖客户端保存相应的标识(如sid),所以依赖于cookie(较好的实现方案)。
session可避免cookie直接存储敏感信息。
以用户登录为例:
1. 用户提交用户名密码的表单(经过前端加密(配合验证码哈希)/HTTPS)
2. 服务端验证用户名密码
3. 如果验证通过, 生成一个会话对象(检查有没有同用户的会话,有就删除,实现单用户登录),里面含有sid,用户名,以及其他敏感信息,如logIn=true
,设置set-cookie:sid=value
4. 下次发起请求时cookie带有sid,服务端通过sid寻找对应的会话并根据状态进行操作。
5. 一个会话不会因为客户端关闭而结束,故一般有过期时间(进行‘登出’操作能主动关闭session)
onStateChange(() => {
view = render(state)
})
即state何时change?(修改setter,进行notify)
render哪些部分?组件内VNode diff
Watcher(监听表达式、回调操作)、Dep(watcher依赖收集)、Observer(其实只是响应化)的相互依赖
具体见
指向定义时的父级的this,自身无this
因为自身无this,所以也不能通过.bind()
、.call()
、.apply()
方法改变this。
如果作为函数被return出来,因为自身无this,所以其实形成了一个闭包,指向上一级的this。
//用例数据
var obj = {
name: 'mike',
sayHi: function(){
console.log(this.name);
},
say: () => {
console.log(this.name);
}
}
var name = 'ben';
//函数部分
function c(){
return () => console.log(this.name)
}
c()();//ben 指向父级的this,父级的this为window
c.bind(obj)()();//mike 指向父级的this,父级的this绑定为obj
c().bind(obj)();//ben bind无效
圆括号 > 成员访问(
.
和[]
) = 带参数的new()
> 函数调用(fn()
) = 无参数的new
> 后置递增/递减(...++ ...--
) > 除扩展运算符外的一元运算符