分类存档: html5

《ES6 标准入门》 阅读笔记

第三章

    1.var {foo:baz} = {foo:"aaa", bar:"bbb"}   //bas = bbb, foo = undefined

    对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者

    

    2.嵌套赋值的例子,平时开发经常会用到

    let obj = {};

    let arr = [];

    ({foo:obj.prop, bar:arr[0]}) = {foo:123, bar:true};

    obj //{prop:123}

    arr //[true]

    3.只要等号右边的值不是对象,就先将其转为对象。

    let {toString:s} = 123;

    s === Number.prototype.toString //true

    

    let {toString:s} = true

    s === Boolean.prototype.toString //true

    4. 交换变量

    es6 :[x, y] = [y, x];

    想到一种es5的写法 x = [y, y = x][0]

第五章

    1.正则表达式的  y修饰符,y修饰符隐含了头部匹配的标志

    var s = "aaa_aa_a";

    var r1 = /a+/g;

    var r2 = /a+/y;

    r1.exec(s) //["aaa"]

    r2.exec(s) //["aaa"]

    r1.exec(s) //["aa"]

    r2.exec(s) //null

    var s = "aaa_aa_a";

    var r = /a+_/y   //换一下表达式

    r.exec(s) //["aaa_"]

    r.exec(s) //["aa_"]

第七章

    1.Array.from() 作用是把类数组的对象转化为真正的数组, 适用于(arguments对象,NodeList,Iterable对象,Set,Map)

    let arr = {'0':'a', '1':'b', '2':c, length:3};

    ES5:

    var arr1 = [].slice.call(arr);

    ES6

    let arr2 = Array.from(arr);

    2.Array.includes()

    [1,2,3].includes(2) //true 方法属于es7

    3.数组推导,可以在[]内用循环创建数组

    var years = [1,2,3,4,5,6,7];

    [for (year of years) if(year>3)]   //[4,5,6] 

第八章

    1.

    function m1({x = 0, y = 0}){

        return [x, y];

    }

    function m2({x, y} = {x:0, y:0}){

        return [x,y];

    }

    

    m1({x:3}) //[3, 0]

    m2({x:3}) //[3, undefined]     //如果有参数,则不取默认参数,然后对{x,y}赋值

    m2() // [0,0]    //如果没有参数,取默认参数

    

    2.函数的length属性 如果指定了默认值后,length 属性将失真

     (function(a){}).length //1

    (function(a=5){}).length //0

    (function(a, b, v = 5){}).length //2

    3. 函数的length属性不包括rest参数

    (function(a) {}).length //1

    (function(…a){}).length //0

    (function(a, …b){}).length //1

    4.  任何类似数组的对象都可以用扩展运算符转为真正的数组(Map,Set,Ceberatir也可以)

    var nodeList = document.querySelectorAll('div');

    var array = […nodeList];

    5. ()=>{console.log(arugments)} 箭头函数函数体内没有arguments对象

    6.箭头函数的管道机制,即前一个函数的输出是后一个函数的输入

    var s = (a)=> b => a * b

    s(2)(3) //6

    7 尾递归可以极大节省内存

       尾递归的实现往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量都改写成函数的参数。

        function factorial(n, total==1){

            if(n===1) return total;

            return tailFactorial(n – 1, n * total);

        }

        factorial(5);

     8 柯里化 的意思是将对参数的函数转换成单参数的形式。

第九章

    1.Object.is   跟全等号===类似

    不同之处有两个

    Object.is(+0, -0); //false

    Object.is(NaN, NaN)  //true

    

    2.克隆对象

    function clone(origin) {

        return Object.assign({}, origin);

    }

     上面的代码将原始对象复制到一个空对象,就得到了原始对象的克隆。

    不过,采用这种克隆,只能克隆原始对象自身的值,不能克隆它的继承值。如果想要保持继承链,如下:

    function clone(origin){

        let originProto = Object.getPrototypeOf(origin);

        return Object.assign(Object.create(originProto), origin);

    }

    3. 属性的遍历

    for…in  //遍历包括自身和继承的可枚举属性

    Object.keys(obj) //只遍历自身的可枚举属性

    Object.getOwnPropertyNames(obj) //遍历自身和继承的属性包括不可枚举的属性

    Object.getOwnProertySymbols(obj) //返回自身所有的Symbol属性 

    Refect.ownKeys(); 

    Refect.enumerate()

    以上的遍历排序按一下规则:

    1.数字优先,按数字小到大排序

    2.其实是字符串,按生成时间排序

    3.最后是Symbol的值,按生成时间排序

    Object.keys({[Symbol():0, b:0, 10:0, 2:0, a:0]})

    //['2', '10', 'b', 'a', Symbol()]

    4.Object.setPrototypeOf 

    可以修改实例的原型链,如 

    let p = {a:1}

    function d(){};

    d.protype = p

    

    let a = new d();

    let c = new d();

    Object.setPrototypeOf(a, {b:1})

    a.b = 1;

    a.a = undefined;

    注意:c.prototype也会受到牵连

    5.如果扩展运算符的参数是null 或者 undefined,则会忽略不会报错

    let emptyObject = {…null, …undefined} // {} ,不会报错 

  

从React diff算法原理中得到的React编写优化方案

    讲起React,当然不能缺少它最重要的特性虚拟Dom,但是很多人都讲不清楚虚拟Dom的内在原理,其实关键点还是这Diff算法。

    

    Diff算法说简单的说就是遍历二叉树,render前和render后的每一个节点做匹配。这里说的节点就是DOM节点但是不是真的DOM节点,而是一个对象类似于

    {

        tagname:div

        className:"a",

        style:"width:100px",

        onClick:function(){}

        children:[

            {

                    tagname:span,

                    className:"b",

                    text:"hello",

                    key:1

            },{

                    tagname:span,

                    className:"c",

                    text:"world",

                    key:2

            }

        ]

    }

    对应的DOM如下:

    <div class="a" style="width:100px" onclick="">

        <span class="b"></span>

        <span class="c"></span>

    </div>

    根据二叉树的遍历,从上到下,从左到右遍历,一边遍历,一遍跟旧节点对比。

    1.如果一些基本属性如class,style,text变化了(注意不包括id,key,children),则只修改对应DOM的 class,style,innerText

    2.如果tagname变化了,那就整个元素删掉,重新creatElement('xx')新的标签。这时候原来的childrem都不会再遍历。

    3.如果对象中有key,而且相对于同级元素唯一,那么对于children数组操作的时候,会按key找到元素,修改对应的值。这样的优势是,如果在children中插入一个新的兄弟元素,比如插入头部,它就会判断children[0]的key,跟新插入的是否一致,如果不一致,则创建新元素,然后匹配下一个兄弟元素,并检索是否在旧的childrem是否存在同样id的节点,如果存在,而且被修改过值,则像上面的 1 一样操作。加key优势是不必全量销毁和创建同级DOM。盗一张图类似这样 

WechatIMG101.jpeg

  1. 加key,只对同级别元素有效

  2. 不要变标签,最好能加css隐藏掉

    {if isOk == true?<div>1</div>:<span>1</span>}像这样的写法需要经过销毁和创建DOM的过程,如果换成

    <div style={{display:isOK?block:none}}>1</div>:<span style={{display:isOK?inline:none}}>1</span>,这样就不会频繁销毁和创建

  3. boolean shouldComponentUpdate(object nextProps, object nextState)

    如果很有把握这次render可以不进行,就可以用这个方法对比props和state,return false;阻止render进行.

http头缓存相关详细总结

http 请求会返还头部信息和主题内容,头部信息分为General,Pesponse, Request:举个例子

blob.png

包含请求地址,方法,状态码,地址:端口

blob.png

包含跨域白名单,连接方式,压缩方式,返回格式,日期,Keep-Alive,还有些服务器相关的东西

blob.png

包含请求格式,接受哪种压缩方式,哪种语言,Cache控制,链接方式,host,Pragme,User-Agent等

这里先着重研究一下keep-alive到底是什么鬼,它对页面打开速度有影响吗?对服务器会增加压力吗?看来需要新开一片文章来说了,暂时放着。

那么,Pargma,与Cache-Control,还有Expires,Last-Modified这些到底是什么关系,相互有什么区别,优先级怎么处理。

blob.png

Pragma 

网上搜了一圈貌似Pragma只有一个值no-cache,用来禁止缓存的

Expires

告诉浏览器过期时间,缺点是需要跟客户端时间匹配,客户端时间不可靠。

[demo0]

Cache-Control 这个功能优点强大,但我们常见的只是用max-age

Cache-Control 提供了5种属性;那么如果同时设置:

Cache-Control :no-cahce,max-age:600; 那到底是缓存还是不缓存?

做个实验试试:

header("Cache-Control:max-age=600,no-cache"); 

[demo1]

缓存成功

header("Cache-Control:no-cache,max-age=600"); //位置换一下

[demo2]

缓存成功

结论:no-cache优先级比max-age 高,与顺序无关;

Last-Modified : 服务器告诉浏览器这个文件的修改时间。

If-Modified-Since:浏览器告诉服务器这个文件的修改时间

Last-Modified 和 If-Modified-Since必须要一起使用。

[demo3]

Etag:服务器给文件生成的唯一标识。

If-None-Match: 浏览器告诉服务器这个文件的标识。

[demo4]

那么既然有5种方法控制缓存,他们都加上的话,优先级又是怎样呢?

Pragma,Expires,Cache-Control ,Last-Modified ,Etag

实验1:

blob.png

[demo5]

结论:每次都请求服务器,证明Pragma生效,所以优先级比其他都高。

那么剩下的Expires,Cache-Control ,Last-Modified ,Etag 优先级又如何?

先比较 Expires,Cache-Control

blob.png

[demo6]

结论:每次都请求服务器,证明Cache-Control生效,所以优先级比Expires高。

再比较 Last-Modified ,Etag 

blob.png

[demo7]

结论:按f5的时候,都请求服务器,同时带上If-None-Match,If-Modified-Since,究竟会不会返回304,这是服务器说了算。所以Last-Modified 和Etag比较是没有意义的。 

然后将两组优先级高的提取出来,Last-Modified和Etag就把他们当中一个东西吧。 

Cache-Control  VS Last-Modified/Etag 

blob.png

结论:每次按地址栏回车都会请求服务器,证明Cache-Control优先级更高。

剩下 Expires VS ast-Modified/Etag 

blob.png

结论:在Expries过期的情况下,每次按地址栏回车,都会请求,证明Expires优先级更高。

最后来个总的排名: Pragma>Cache-Control>Expires>Last-Modified||Etag

操作行为对资源缓存的影响:

blob.png

按Ctrl+F5就没啥好说的啦,强制刷新,其实就是If-None-Match,If-Modified-Since都不会带上,导致服务返回200;

按F5的话其实都会请求服务器,但是如果有Last-Modified/Etag,那么就会带上If-None-Match/If-Modified-Since。服务器判断是否返回304

其他操作行为都不会请求服务器

最终结论,如果Expires,Cache-Control ,Last-Modified ,Etag存在,那么以Cache-Control 为准。

关于DOMContentLoaded的触发时机探究

相信很多人都知道DOMContentLoaded,也就是$.ready(),是在页面DOM构建完之后触发的。

今天突然想到一个问题,这个DOM构建完是指HMTL解析器解析成DOM之后算是构建完,还是渲染的最后一步绘图结束后算是构建完。

直接看图吧:

blob.png

也就是DOMContentLoaded是在 (1) 还是(2)阶段触发呢?

[demo],在demo中可用看的黄色的DIV已经显示在屏幕上了;

证明我们常说的DOMContentLoaded,正确的理解是页面首次渲染完毕时触发

页面缓存总结篇

一.cookies

二.Express

三.locationStronge

四.application cache

五.WebView 终端辅助

todo….

使用grunt构建seajs项目

1.安装nodejs

2.安装grunt-cli

npm install -g grunt-cli

3.进入到项目目录,同时准备好package.json和Gruntfile.js文件 继续阅读 »

双人打飞机项目经验分享

前段时间前期后后断断续续大概花了4个月的时间去完成我的双人打飞机游戏,我做这个游戏的初衷是为了给自己一个机会去探索html5的canvas和nodejs的使用,最后坚持把游戏写出来了。

Screenshot_2013-12-30-21-09-15

刚开始我只是想做一款在电脑上用html5实现的一款打飞机的单人游戏: 继续阅读 »

关于html5打飞机遇到的一些问题

最近在模仿微信打飞机游戏,遇到的一些问题。简单描述一下:

1.画布读取问题,

继续阅读 »

html5 audio 游戏开发的那些让人抓狂的问题

最近在研发的一款html5打飞机游戏,当我正在给他配音的问题时,发现很多巨坑。

没仔细接触过audio可能以为这是一个播放音乐的标签,没什么好研究的,我以前也是这么想,仔细运用到游戏的复杂环境里面,简直让人抓狂。 继续阅读 »

记录html5——canvas的那些坑

1.putImageData 第3个以后的参数在chrome不支持,在我测试的时候2013.9.28 以后应该会改善
<script type=”text/javascript”>
var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
var image = new Image();
image.src = “face.jpg”; 继续阅读 »