《JavaScript高级程序设计》第二次阅读笔记

第二章

  1. <!CDATA[   javascriptCode  ]]>   在XHTML中javascript可以用这个标记保证内嵌的javascript代码能正常运行,因为XHTML标准比较严格,很多标签都不能被解析。

  2. defer和async标记都不能保证是在DOMContentLoading之前或之后执行,区别就只是保证顺序执行而已。

第三章

  1. 严格模式下,使用未定义的变量会导致错误。

  2. nul值表示一个空对象的指针,而这也是使用typeof操作符检测null值时返回“object”的原因

  3. 无论在什么情况下都没必要把一个变量的值显式地设置为undefined,但是对于null,只要在保存[对象]的变了还没有真正保存对象,就应该明确地然它保存为null值。

  4. undefined 和 null,没有任何属性和方法

   5.要把都一个值转换为字符串,可以用加号把它与一个字符串“xxx”加在一起

   6.并非所有浏览器的BOM与DOM都属于Object

   7.+操作符 会像Number()一样对这个值执行转换。-号同理,不过变成负数。

   8.do-while 循环的代码至少会执行一次。

   9.for(; ;){ doSomething(); } 无限循环

   10.通过for-in循环输出的属性名的顺序是不可预测的,具体先后顺序因浏览器而异。

   11.swicth{case xxx:} 在比较时是使用全等操作符 ===,所以10不等于“10”

   12. 标准模式下arguments与参数会相互同步,严格模式下不会同步。

标准模式下:
function add(a){
arguments[0] = 10;
console.log(a); //10
}
add(1);
严格模式下
function add(a){
        "use strict";
arguments[0] = 10;
console.log(a);//1
}
add(1);

第4章

  1. 给基本类型添加引用会被浏览器直接忽略,也不会报错。

   2.要检测一个变量是不是基本数据类型用typeof,typeof null 等于object。如果用instanceof操作符检测基本类型的值,则翻回false.

第5章

   1.对象的key只能用字符串作key

   2.数组的toString()方法会返回由数组中每一个值的字符串形式拼接逗号分隔而成的字符串。所以如果[{a:1},2] toString() 等于 [object Object],2

   3.concat()方法可以添加字符串,也可以添加数组。如:

    var colors = ["red","green","blue"];

    var colors2 = colors.concat("yellow",["black","brown"]);

    alert(colors);//red,green,blue

    alert(color2);//red,green,blue,yellow,black,brown

   4.Array的5个迭代方法,都是给定运行参数function(value,index,array){}

    1.every() //返回布尔值,每一项都是true的话,返回true

    2.filter() //将返回true的项组成新的素组

    3.forEach()//仅仅循环数组一次.没有返回值

    4.map()//将每一项的返回值组成新的数组

    5.some()//返回布尔值,其中一项返回true,则返回true

   5.关于函数是否能复制,目前只能想到eval 这种方法了 eval("var z = "+s1.toString());

   6.创建函数有一种新的思路

      var sum = function(num1, num2){

              return num1 + num2;

      }

    等于

   var sum = new Function("num1","num2","return num1 + num2");

    7.严格模式下,访问arguments.callee会导致错误。

    8.函数的length等于参数的数量,如function a(a,b){}; a.length //2

    9.在严格模式下,作为方法调用,则this等于undefined,在非严格模式,等于window.

    10.用Boolean,Number,String创建的变量,与直接定义同名的基本类型不一样。

    var value = "25";

    var number = Number(value); //转换函数

    alert(typeof number);  //number

    var obj =new Number(value); //构造函数

    alert(typeof obj); //object

    主要表现在number就是number类型的基本类型,但是obj是一个number对象,它各种属性都跟基本类型一样。

  10. slice(开始index,结束index)

         substr(开始index,length)  

         substring(开始index,结束index)  开始和结束都不接受负数。

   11.所有全局作用域中定义的属性和函数,都是Global对象的属性。如isNaN(),isFinite(),parseInt(),parseFloat();

第6章

    1.只要创建一个新函数,就会为该函数创建一个prototype,并自动获得constructor属性指向函数本身。

    2.alert(Person.prototype.isPrototypeOf(person1));//true

      isPrototypeOf可以检测person1的prototype属性是否属于Person

   3.person1.hasOwnProperty("name") //hasOwnProperty方法可以确定属性存在方法中还是存在实力中。

   4."name " in person1 //单独使用in操作符会在通过对象能过访问属性时返回true。

   5.通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。

第7章

    1.

    var name = "the window";

    var object = {

        name : "My Object",

        getName: function(){

            return this.name;

        }

    }

    object.getName();    //"My Object"

    (object.getName)(); //"My Object"    object.getName == (object.getName)

    (object.getName = object.getName)();//"the window"  相当与x=object.getName;x();

第8章

    1.iframe框架之间使用instanceof不适用

第9章

    1.每次修改location的属性(hash除外),页面都会以新的url重新加载;location="xxx" 等于loaction.pathname="xxx"

第10章

    1.如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置。

    2.如果参照节点是null,则insertBefore()与appendChild()执行相同的操作。

    3.cloneNode()//在参数为true的情况下,为深度复制,复制节点和整个子树;在参数为false的情况下,为浅复制,只复制节点自己。

       cloneNode 不会复制绑定事件。

    4.document.write();在页面呈现的过程中运行,则之间向页面追加内容。如果在加载结束后调用document.write();则重写整个页面。

第11章

    1.footer.dataset.xx="asd";等于<footer data-xx="asd"></footer>  //可以取代setAttribute('data-asd',"xx");的方法。

     2.一个更强大的DOM操作方法:insertAdjacentHTML(); 有4种插入模式:

        beforebegin:     //作为前一个同辈元素插入

            element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>")

        afterbegin:        //作为子元素在内容前插入

            element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>")

        beforeend:        //作为子元素在内容最后插入

            element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>")

        afterend:        //作为后一个同辈元素插入

            element.insertAdjacentHTML("afterend", "<p>Hello world!</p>")

第13章

    1.ie8及以前的版本只支持attachEvent,只在冒泡阶段触发。

    2.ie和其它浏览器触发顺序有点相反

        footer.addEventListener('click',function(){alert(1);})

        footer.addEventListener('click',function(){alert(2);})

        先显示1,再显示2

        footer.attachEvent('click',function(){alert(1);})

        footer.attachEvent('click',function(){alert(2);})

        先显示2,再显示1

    3.event.currentTarget //仅代表被绑定的那个元素。当用事件代理时,currentTarget!=target

    4.只有cancelable属性设置为true的属性,才可以使用preventDefault()来取消默认行为。

    5.只有在设置了<script>元素的src属性并添加到文档后,才下载javascript文件

    6.在unload事件中访问dom,不一定能访问。看浏览器而异。

    7.浏览器最小化也会触发resize事件

    8.除了mouseenter和mouseleave,所有鼠标事件都会冒泡。

    9.针对mouseover和mouseout事件,event对象的relatedTarget提供了相关元素的信息。

第14章

    1.tabIndex:表示当前字段的切换(tab)序号 

    2.对于<input>和<textarea>元素,当失去焦点且value值被改变时,才会触发chang事件

       对于select,只要选择了不同的选项就会马上触发。

    3.表单的selectionStart/selectionEnd属性       //可以知道选择字符串的位置

    4.document.designMode = "on";可以使文档的text处于可编辑状态

    5.<div contenteditable >1</div>  //使某个元素处于可编辑状态

    6.document.execCommand("bold",false,null); //用这个命令可以实现大部分的编辑器功能。

    7.document.getSelection();  与选中文本相关的api

第20章

    1.JSON.stringify(obj, [key1,key2]|function(key,value){return xxx},int缩进空格数);

        JSON.stringify有第二个参数,这个参数可以是数组,也可以是函数。

        如果是数组,则返回数组中只返回数组中列出的key;

        如果是函数,例子:

var json = {"a":1,"b":2,"c":3}

var sx = JSON.stringify(json,function(k,v){
	switch(k){
		case "a":
			return 4
		case "b":
			return 5;
		case "c":
			return 6;  //如果是undfined或是没返回则最终数组是{"a":4,"b":5}
		default:
			return v;
	}
})
console.log(sx); //{"a":4,"b":5,"c":6}

这里要注意,default不仅是为了返回abc以外的key,函数第一次运行,返回的k是空字符串,v是json。若这时候改变v,则后面的k将按照改变后的v进行操作。

    2.toJSON方法

    var json = {"a":1,"b":2,"c":3,d:{"c":4,toJSON:function(){ return this.c}}}

   JSON.stringify(json);// "{"a":1,"b":2,"c":3,"d":4}"

    如果在只要有一个对象,不管是父对象还是子对象,有名叫toJSON的方法的时候,真个对象可以用这个方法作为过滤。

asdd.png

巧用JSON的第二个参数,可以做到很多事情。

   3.JSON.parse也有第二个参数作为函数的方法

JSON.parse('{"a":1}',function(key,value){

console.log(value);

});

    这里会触发2次,第一次是1,第二次是对应的空对象或者空数组。

第22章

    1. function isArray(value){

            retrun Object.prototype.toString.call(value)  == "[object Array]"

    }

     function isFunction(value){

            retrun Object.prototype.toString.call(value)  == "[object Function]"

    }

    用于检查是否原生数组或者方法。

    2.防篡改对象:

        1.Object.preventExtensions();    //不能增加,但可以修改删除

        2.Object.seal()   //不能增删,但可以改。

        3.Object.freeze() //完全密封,既不能改,也不能加属性

    3.setInterval();

        1.某些间隔会被跳过

        2.多个定时器的代码之间的间隔可能会比预期小。

第24章

    1.尽可能做好初始化类型:

        var found = false;    //布尔型

        var count = -1;    //数字

        var name = ""; //字符串

        var person = null; //对象

     2.关于事件回调处理的最佳事件

         1.勿将event对象传给其它方法;只传来自event对象中所需的数据

         2.任何可以在应用层面的动作都应该可以在不执行任何事件处理程序的情况下进行

         3.任何事件处理程序都应该处理事件,然后将处理转交给应用逻辑。

     3.Page Visibility API 可以知道页面处于最小化,还是标签页中,还有触发事件。

关于instanceof的深入认识

如果刚认识这个操作符,有个肤浅的理解

a instanceof b 只要在a的原型链上有b就返回true。这个理解其实是错的。

直到我重新读了一下《javascript高级程序设计》的6.3节 173页。

function inheritPrototype(subType, superType){
	var prototype = Object(superType.prototype);
	prototype.constructor = subType;
	subType.prototype = prototype;
}

function SuperType(name){
	this.name = name;
	this.colors  = ["red","blue","green"];
}

SuperType.prototype.sayName = function(){
	alert(this.name);
}

function SubType(name,age){
	SuperType.call(this, name);
	this.age = age;
}

inheritPrototype(SubType,SuperType);

SubType.prototype.sayAge = function(){
	alert(this.age);
}
var instance = new SubType("jie",29)

instance instanceof SubType //true 这个没有异议吧

instance instanceof SuperType //true 这个就比较奇怪了

如果console.log(instance);是看不到SuperType出现在instance的原型链上面的。

于是我上百度谷歌了一下:

a instanceof b底层的运算机制关键点如下:

1 b的数据类型必须为[object Function],否则就抛TypeError;

2 若a为Primitive Value则直接返回false, 若a的数据类型为Object则执行后续运算;

3 当且仅当b.prototype位于a的prototype chain中时,才返回true(由于Object.prototype.__proto__为null,因此prototype chain是有限链表);

所以正确的说法是   a instanceof b 只要在a的原型链上有等于b的原型就返回true

对象属性的理解

var person = {name:"jie",age:18};
如果只是这样定义一个object,那么configurable:true,Enumerable:true,writable:true;

要改变这些属性类型,需要显式的调用Object.defineProperty
Object.defineProperty(person,"name",{
    configurable:false, //能否被删除,能否修改访问属性,默认true,如果在false重设defineProperty会报错
    Enumerable:false,//能否被for-in,默认为true
    writable:false, //能否修改,默认为true
    value:"gax"
})

console.log(person); //{name: "gax",age:18}
person.name = "abc";
console.log(person); //{name: "gax",age:18}

[configurable]
Object.defineProperty(person,"name",{
    configurable:false,
	value:"jie"
})
delete person.name; //报错
Object.defineProperty(person,"name",{
    value:"jie2"
})//报错
configurable如果被设置false,那么如果delete会报错,如果configurable,Enumerable,writable,value中,任意一项于初始值不一致,都会报错

[Enumerable]
var person = {name:"jie"};
Object.defineProperty(person,"age",{
    Enumerable:false,
	value:"18"
})

for(var x in person){
	console.log(x);
}
//只有name

[writable]
var person = {};
Object.defineProperty(person,"age",{
    writable:false,
    value:"18"
})
person.age = 21;//依然是 18

如果
var person = {};
Object.defineProperty(person,"age",{
    value:"18"
})
那么Object.getOwnPropertyDescriptor(person,"age")//{value: 18, writable: false, enumerable: false, configurable: false}
全部未定义的默认全部false

同理适用于new出来的实例:
function person(){
	Object.defineProperty(this,"age",{
		writable:false,
		value:"18"
	})
}
var son = new person();
这样就能做到对象中的权限控制。

当变量提升遇到作用块

function aaa(){
    a();
    if(true){
        function a(){
            console.log(1);
        }
    }
    if(false){
        function b(){
            console.log(2)
        }
    }
    function a(){
        console.log(3);
    }
}
与
function aaa(){
    a();
    function a(){
        console.log(3);
    }
    if(true){
        function a(){
            console.log(1);
        }
    }
    if(false){
        function b(){
            console.log(2)
        }
    }
}

结果都是3,证明fuction的变量提升是只在当前作用块内。

关于图片阻塞的探索

我现在正在给m.360zfw.com做首屏速度优化,对于图片阻塞这一块,有以下问题

问题1:img上的图片阻塞是否会影响首次页面渲染

demo

现象:div.a div.b 同时出现,3秒后出现头像

结论:说明img不会阻塞首屏渲染。

问题2:那么background-images上的图片呢?

demo

想象结论同上。

关于JS页面阻塞的实验

问题1:如果遇到JS阻塞,那么它的阻塞是指阻塞DOM建立,还是阻塞显示(渲染),如果是阻塞DOM建立,那么是全部DOM都阻塞还是部分阻塞?

[DEMO]

现象:先出现红色,3秒后出现蓝色。

结论:说明JS只是阻塞JS脚本下面的DOM。

问题2:如果这个JS阻塞不是因为外链下载消耗的阻塞,而是<script>内部js的计算运行造成的阻塞,那么<script>上面的DOM会被渲染吗?

[DEMO]

现象:红色蓝色一起出现。

结论:说明JS脚本的阻塞如果是[网络原因],就会部分阻塞,如果是[运行原因],就会全部阻塞。

关于 Android Webview SDK 的研究

《CSS权威指南》重点笔记

CSS这东西很多人都懂,都是一知半解,能做出效果就行。but~相信这都是入门级的伪前端。因为我曾经也是,大学开始到腾讯离职后都认为CSS很简单,认真学下来,Css还是很有禅意的。

一下是我阅读《CSS权威指南》时的一些重点,或者是一些平时忽略的细节,按章节区分

第1章:

    1.建议每一个css结尾时都加上;号

       不建议 div{color:red;background:red}

       建议div{color:red;background:red;}

第2章:

  1. 所有class 和 id 都区分大小写。[demo]

第3章:

   1. css选择器的优先级用0,0,0,0标示;

第一个0,代表标签上的style

第二个0,代表id

第三个0,代表class

第四个0,tagName和伪元素

如h1{color:red}  0,0,0,1  ,pem{color:red}  0,0,0,2

2.带style中!important标志权重比内嵌style还高,内嵌style+!important权重最高  [demo]

第4章:

关于em单位的理解:在设置字体大小时,em的值会相对于父元素的字体大小,除了设置字体以外,比如width,padding,margin,border时用em,是相对于当前字体,并不是父元素[demo]

第5章:[demo]

1.serif字体  字体成比例(即不同文字如M和i所占据的宽度不一样),而且有上下短线 

   Sans-serif字体  字体成比例,而去没有上下短线

   Monospace 字体不成比例,有固定宽度,不一定有短线

2.一般font-weight:normal == 400/bold == 700

           font-weight:bolder //比所继承值更粗的一个字体加粗

3.font-size可以继承,不过继承的是计算值而不是百分数;

   p{font-size:12px;}

   em{font-size:120%;}

   strong{font-size:135%}

   12px * 120% = 14.4px;浏览器可能认为是15 或者 14

   14.4px*135% = 19.44px;浏览器可能认为是20 或者 19

 

4. 在font简写中要注意:font-size,font-family必须存在,而且位置必须font-size在前 ,其它值可选

    font:[[font-style||font-weight||font-variant]?font-size,font-family] [demo]

5.字体匹配规则:

   1.用户本地有一个字体数据库。

   2.根据font-family查询数据库,如果查得到

      a.匹配font-style

      b.匹配font-variant

      c.匹配font-weight(这个匹配不可能失败)

      d.匹配font-size(这个匹配可能有误差,或20%,或10%根据浏览器而异)

   3.如果第二步匹配失败,接着下一个代替字体循环上一个步骤。

   4.如果匹配到一个字体,但是没有版权,接着下一个代替字体循环步骤2。

   5.如果都没匹配成功,则按照通用字体系列选择默认字体,尽可能的显示这个元素。

   例如:

            font-family:"Microsoft YaHei","宋体",Arial,Helvetica,sans-serif;

            某ios不含Microsoft YaHel,或没有版权,则接着到宋体,如果没匹配成功,则一直到sanf-serif的通用字符系列选择默认字体

第6章

  1. line-height 可以使用缩放因子,取代em,避免继承问题[demo]

第7章

    1.如果设置width,margin-left,margin-right中的某个值为auto,余下的两个属性为特定值,则设置auto的属性会自动扩张,直到width+margin-left+margin-right=父元素width;以前认为设置auto,表示默认,或者0,或者反正效果出来了就行。。。真TMD伪前端啊 [demo]

    2.如果border-style被设置了,则border-width:为medium. 到底是多宽由浏览器定义。[demo]

    3.vertical-align会改变行内框高度,前提是这个行内框顶端已经是行中最高点[demo]

    4.vertical-align:middle  是将元素行内框的垂直重点与父元素基线上0.5ex处的一点对齐。可理解为x的中间位置。[demo]

    5.内边距和边框不改变行高 [demo]

    6.行内元素包含块元素,不合法,如:

       <a style="display:block">

            <p style="display:inline">I'm a block</p>

       </a>

       即使改变显示角色 也不会使以上标记变得合法。display之所以得名是因为它影响的是元素如何显示,而不影响它是何种元素。

     7.width 和 text-align不能应用于行内元素

第8章:

     1.百分数值定义为相对父元素的width,这不仅应用于左右外边距,也应用于上下外边距。[demo]

     2.如果边框没有声明颜色,它将于文本颜色color颜色相同。[demo]

     3.元素的背景会伸延至边框,background-position默认值在内边距的左上角 [demo]

   

     4.border-style:transparent;  透明边框 [demo]

     5.百分数值定义为相对父元素的width,这不仅应用于左右内边距,也应用于上下内边距。原理同(1)一样[demo]

     6.可以向图像应用内边距[demo]

第9章:

     1.background-position如果用百分比表示,那么百分比同时应用于元素和图像[demo]

   

     2.296页的一幅图,总觉得有问题,为什么div4会掉下去而不是叠在div3下面呢?[demo

        B21F0491-05B4-4A4A-867E-DB067891A13E.png

   3.如果一个浮动元素在内容流过的边上有负外边距,文字会叠在浮动元素上边[demo]

   4.带clear:both的元素上外边距之上增加的margin-top在float的上内边距以内是没有效果的。[demo]

  

   5.对于一个非根元素,如果其position值是relative,则包含块就是它的父元素

   6.关于left,top,right,bottom的定位,是在包含块的左上角边框内边界,到定位元素的外边距边界[demo]

   7.定位元素的高度和宽度可以由这些定位属性偏移隐藏确定,仅适用于absolute定位的元素 [demo]

   8.如果一个设置了visibility为hidden的元素的子元素设置了visibility为visible,那么这个子元素也是可见的。 [demo]

   9.绝对定位元素的left,top,right:auto时,与其“静态”位置一致。注意(auto不是一般认为的0) [demo]

   10.如果left,width和right都设置auto,那么左边界位于其静态位置,width则设置为“收放得正好合适”[demo]

    11.绝对定位元素中,若margin:0 auto,左右外边距auto,同时left,right都有固定值,那么auto会使元素相对于left,right居中,同理可以垂直居中。[demo]

第12章:

    1.CSS2.1明确定义:before,:after,如果主体是块级元素,那么只能display:nine,inline,block。

       如果主体是行内元素,那么display只接受none和inline;

附录:

    :first-letter   h1:first-letter{color:red;} 作用于第一个字母

    :first-line   p:first-line{color:red;} 作用于第一行

关于vertical-align的一些理解

写完 关于行高,基线的理解 这篇文章之后,终于到这篇文章了,只有深入了解了基线问题之后,才能搞懂vertical-align

在写这篇文章之前,vertical-align对我来说就是一个能调整图片和文字之间垂直问题的一个css,但是这个属性很奇怪,有时候有效,有时候无效,而且它奇奇怪怪的属性很难懂,于是我就试着使用绝对值,调得差不多就行了。为了未来攻破这个难关,于是这篇文章诞生了。

这是截取自w3cshool的图片

8F694468-5186-4DDF-A571-DA80F15467E1.png

注意:

  1. vertical-align只对inline/inline-block元素有效。

  2. vertical-align的定位只跟父元素有关,跟兄弟元素没直接关系。

baseline:如何确定父元素的基线呢?看这里关于行高,基线的理解 

sub/super:关于上下标,这更各个浏览器实现有关系,我的理解是文字的上线和文字的底线位置。

bottom:下标其实就是line-height = 0,不包括padding的地方,与元素顶端对齐

top:line-height 的位置,不包括padding的地方,与元素底端对齐

text-top/text-bottom:与字的顶线/底线对齐。

middle:基线+ex/2的位置 1ex = 0.5em

length:与基线做为起点加减具体位置,如:10px/-10px/1em

%:同样是以基线为起点,以line-height做为基数计算出来的偏移量,可以是正数负数。

参考文章:http://www.zhangxinxu.com/wordpress/2010/05/%E6%88%91%E5%AF%B9css-vertical-align%E7%9A%84%E4%B8%80%E4%BA%9B%E7%90%86%E8%A7%A3%E4%B8%8E%E8%AE%A4%E8%AF%86%EF%BC%88%E4%B8%80%EF%BC%89/

http://www.w3school.com.cn/cssref/pr_pos_vertical-align.asp

《CSS权威指南》

关于行高,基线的理解

1.  基线、底线、顶线

行高

  • 行高指的是文本行的基线间的距离。

  • 基线并不是汉字的下端沿,而是英文字母"x"的下端沿

2.  行距、行高

行距和行高

3.  内容区

内容区

  • 底线和顶线包裹的区域,实际中不一定看得到,但却是存在。

4.  行内框

行内框

  • 行内框只是一个概念,它无法显示出来,但是它又确实存在

  • 它的高度就是行高

  • 在没有其他因素(padding)影响的时候,行内框等于内容区域

5.  行框

行框

  • 行框(line box)。同行内框类似,行框是指本行的一个虚拟的矩形框

  • 行框高度等于本行内所有元素中行高最大的值

完全参考: http://www.cnblogs.com/rainman/archive/2011/08/05/2128068.html#m1