no pain no gain
早上起床神经质了一把
忽然意识到
对待工作应该和对待女朋友是一样的
短期热血的稀罕只能带我来到山前,持久的热爱和专一,才能帮助向上攀爬,没有痛苦,就没有成长
只是我在从实习到现在花了2年半的时间才意识到
早上起床神经质了一把
忽然意识到
对待工作应该和对待女朋友是一样的
短期热血的稀罕只能带我来到山前,持久的热爱和专一,才能帮助向上攀爬,没有痛苦,就没有成长
只是我在从实习到现在花了2年半的时间才意识到
用String()来确定某一变量是null或undefined
var vUndef, vNull = null;
String(vUndef); // "undefined"
String(vNull); // "null"
String(vUndeclare); // ReferenceError: vUndeclare is not defined
ES5中这样描述:
The String Constructor Called as a Function
When String is called as a function rather than as a constructor, it performs a type conversion.
String ( [ value ] )
Returns a String value (not a String object) computed by ToString(value). If value is not supplied, the empty String "" is returned.
直接调用String()作为方法时,将会执行类型转换,返回经过ToString(value)得到的字符串字面量(与new String()不同),或者空字符串('').
非Number类型调用时:
Number调用时:
这里假如有数字m:
Object的实例拥有以下方法:
使用前置递增或递减操作符,更改被操作对象的值
var a0 = 29;
var b0 = --a0 + 2;
a0; // 28
b0; // 30
var a1 = 29;
var b1 = a1-- + 2;
a1; // 28
b1; // 31
将字符转为32位2进制显示,第32位为符号位
var a = 9; // 1001
var b = 5; // 0101
a & b; // 0001 即 1
var a = 9; // 1001
var b = 5; // 0101
a | b; // 1101 即 13
var a = 9; // 1001
~a; // 0110 即 6
var a = 9; // 1001
var b = 5; // 0101
a ^ b; // 1100 即 12
var a = 9; // 1001
var b = 5;
a << b; // 100100000 即 288
var a = 9; // 1001
var b = -3; // -0101
a >> 3; // 1
b >> 3; // -1
var oldValue = -64; //equal to binary 111111111111111111111111110 00000
var newValue = oldValue >>> 5; //equal to decimal 134217726
字符串比较的是想通位置每个字符的字符编码的值:
'Back' < 'at'; // true 大写B的编码小于a
'23' < '3'; // true <两边都是字符,而'2'小于'3'
任何操作数与NaN进行比较,结果都是false
'a' > 3; // false
NaN > 3; // false
NaN <= 3; // false
假使有x == y:
等号是不可传递的:
new String('a') == 'a'; // true
'a' == new String('a'); // true
new String('a') == new String('a'); // false
ECMAScript没有goto语句,但是有label语句来满足循环嵌套中的跳转问题:
var num = 0;
outer:
for (var i = 0; i < 10; ++ i) {
inner:
for (var j = 0; j < 10; ++ j) {
if ( i == 5 && j == 5 ) {
break outer;
} else if (j == 3) {
continue inner;
}
++ num;
}
}
alert(num); // 49
break outer会中断outer的执行,也就是整个循环嵌套,continue inner则会跳过inner当前的执行,到下一次循环
'use strict';
void function fn(a) {
alert(arguments[0]);
a = 2;
alert(arguments[0]);
}(1)
// 两次都是1
严格模式下,函数的参数不能有相同名称的变量:
function test(a, a) {'use strict';}
结合ES5,重读《JavaScript高级程序设计》,希望把书读薄点儿。 刚开头,看了下数据类型,这里主要记录了Null、Boolean、Number
6种数据类型:
typof的返回值有: "undefined" "object" "boolean" "string" "number" "function"
ECMAScript关于typeof操作的定义The typeof Operator
对比发现,少了null,因为null表示一个空对象的指针:
typeof null; // "object"
// 未定义的
// var age
// 未初始化的
var msg;
// 调用方法
console.log(age); // 报错
console.log(msg); // undefined
但是typeof方法返回的是同一个值:
typeof age; // undefined
typeof msg; // undefined
undefined是派生自null的,ECMA-262规定他俩的相等性检测,返回true
undefined == null; // true
这里处于比较的目的,是做了操作数转换的,因此,严格模式下并不相等:
undefined === null; // false
采用IEEE754格式来表示整数和浮点数(因此也拥有IEEE754对于浮点数处理的bug)
Infinity无法参与数值计算,可用isFinite函数来检测:
var a = Number.MAX_VALUE + Number.MIN_VALUE;
console.log(isFinite(a)); // true
NaN——非数值(Not a Number),同时无法转换成数值,与任何值都不想等,可用isNaN检测:
NaN == NaN; // false
isNaN(NaN); // true
isNaN("10"); // false,可以被转换成数值
isNaN(false); // false,可以被转换成数值
isNaN("number"); // true,非数值,同时,无法被转换成数值
isNaN同样可以用来检测对象,在基于对象调用isNaN函数时,会首先调用valueOf()方法,然后确定该方法的返回值是否可以转换为数值。如果不能,则基于这个返回值再调用toString()方法,再测试返回值。这个过程也是ECMAScript中内置函数和操作符的一般执行流程。
valueOf()与toString()是所有ECMAScript对象拥有的内置方法。操作对象时,valueOf()和toString()会被隐式的调用。
valueOf()方法的目的是将对象转换成最有意义的原始值([[PrimitiveValue]])。即ECMAScript的5种基本类型中的三种,布尔值、数字、字符串。
true.valueOf(); // true
1..valueOf(); // 1
'str'.valueOf(); // "str"
null.valueOf(); // TypeError
undefined.valueOf(); // TypeError
({k: 'v'}).valueOf(); // {k: 'v'},对象本身
[1,2,3].valueOf(); // [1,2,3],数组本身
ECMAScript-262中这样描述valueOf()方法:
When the valueOf method is called, the following steps are taken:
- Let
Obe the result of calling ToObject passing the this value as the argument.- If
Ois the result of calling the Object constructor with a host object (15.2.2.1), then
- Return either
Oor another value such as the host object originally passed to the constructor. The specific result that is returned is implementation-defined.- Return
O.
当valueOf方法被调用时,会调用内置的ToObject,并将this作为参数传进去。ToObject检测会根据参数类型进行数值的转换:
toString()方法的目的是将对象转换成一个有意义的字符串。
true.toString(); // "true"
1..toString(); // "1"
'str'.toString(); // "str"
null.toString(); // TypeError
Object.prototype.toString.call(null); // "[object Null]"
undefined.toString(); // TypeError
Object.prototype.toString.call(undefined); // "[object Undefined]"
({k: 'v'}).toString(); // "[object Object]"
[1,2,3].toString(); // "1,2,3"
ECMAScript对象的大多数操作的转换结果是字符串,这两个方法的结果是相同的。但是如果操作的对象为Number、Boolean或者Date,结果就不同了。
简单来说,在对像操作的隐式转换时,先根据前文线索(hint),如果hint是String,即字符串操作,则先调用toString()方法,没有返回值,再调用valueOf()方法;如果hint是Number,则正好相反。如果没有hint,则默认hint为Number。参见[[DefaultValue]] (hint)。
var obj = {
toString: function() {
return 'invoke toString';
},
valueOf: function() {
return 123;
}
};
obj + '!'; // "123!"
alert(obj); // "invoke toString"
关于toString和valueOf的转换见此文Conversion, toString and valueOf。有时间,再把他翻译了
关于对象的原始值(Object to PrimitiveValue)的转换,可以参考这篇文章Object-to-Primitive Conversions in JavaScript
关于+操作,首先计算左边表达式,调用GetValue()取得左边表达式的值;再计算右边表达式,调用GetValue()取得右边的值;之后将左边value求原始值(primitiveValue),再求右边原始值;如果左边或者右边原始值是string,则调用ToString拼接字符串;否则,调用ToNumber求和。参见The Addition operator ( + )
有3个函数可以将非数值转换为数值:Number()、parseInt()和parseFloat()。
Number()可以将任何非数值,转换为数值。Number ( [ value ] ),将调用ToNumber来计算返回值:
对于字符串的操作比较复杂:
Number("00123"); // 123
Number("01.1"); // 1.1
Number("0xf11"); // 3857
Number(""); // 0
Number("00xf11"); // NaN
parseInt(string, radix)方法,用于将字符串(string)转为响应进制(radix)的整形数字。
字符串(string)将忽略前导0、空格和其他制表符(\n、\t、\r)。
radix未定义或者是0,则默认以10进制计算。除非string是以0x或者0X开头的(将以16进制计算)。如果设置了radix为16进制,可以选择是否以0x或0X开头。
ES3(ECMAScript-262 第三版)中会默认以0开头的,浏览器实现上可以按8进制计算,或者按10进制,但是ES5中已经去掉,即按10进制计算。类似的,《高程(第2版)》第3.4节Number类型(27页),关于parseInt('070')为默认以8进制计算的说法,目前是不适用的
parseInt('00000012.2'); // 0
parseInt(' 0000 \t\n\r 12.2'); // 0
parseInt(' \t\r\n000012.2'); // 12
parseInt(' 0000012 ') * 2; // 24
0000012 * 2; // 10
parseInt被调用时:
-开头,则为负数0x或者0X前缀,如果剩余为空,返回NaNparseFloat()不再介绍,详情见parseFloat (string)
这里有一套题Are You a JavaScript Guru? Try This Test(需翻墙),其中至少有十道题都多多少少涉及这一部分相关的内容:
答案是(请自行翻译):
1100011011101000001101001011101100011101001100011101011110011100101101101101011100111101011110001110011101111110011100111000001000001000001000001100101011101000001100110110000111011001110011110010110000010000010000010000011001110111010000010001011011101110101110110111000101100101111001010001010000010000010000010000011010010111010000010001011100111110100111001011010011101110110011110001010000010000010000010000011010110111010000010001011011111100010110101011001011100011111010010001010000010000010000010000011011010111010000011000111000010000010000010000010000011011110111010000011011110000010000010000010000011100010111010000011001101100001110110011100111100101100000100000100000100000111001101110100000100010110001110000100010100000100000100000100000110001110000101110100000110010111000100000100000100000100000110001110001101110100000101101110001100000100000100000100000110001110010101110100000101101110000010001011000111000101000001011101
这里还有一套题Test – Are you a Javascript Guru?(表打我,鲁迅先生《野草集》都有“我家门前有两棵树,一颗是枣树,另一颗还是枣树”的经典,我也用下……),其中至少五道题与这次内容相关。
计算result的指:
答案是(请自行翻译):
11000110111010000010001011000111000011000110001010000010000010000010000011001010111010000010001011000011011001100010101100110001110001010000010000010000010000011001110111010000010001011000011101011000101000001000001000001000001101001011101000001100111000001000001000001000001101011011101000001001110110000110011101000001000001000001000001101101011101000001101111000001000001000001000001101111011101000001100110110000111011001110011110010110000010000010000010000011100010111010000011101001110010111010111001011000001000001000001000001110011011101000001100110110000111011001110011110010110000010000010000010000011000111000010111010000011001101100001110110011100111100101
这里还有一套专门针对数值转换的题目——JavaScript Quiz [x + 0 == x - 0]
原文地址是:http://calendar.perfplanet.com/2012/proactive-web-performance-optimization
文章作者Marcel Duran,也是YSlow的作者,twitter前端工程师,之前是Yahoo性能团队leader
简单意译了一下,看官勿喷。同时,期望能够在未来i版上使用此方式
PWPO——Proactive Web Performance Optimization,姑且翻译作前瞻性Web性能优化。
开发者对于Web性能必须时刻保持警惕,尤其是在发布新版本迭代新功能时,bug修复或者其他乱七八糟,看似八竿子打不着的事情,都可能会影响到性能,破坏终端用户的体验。
正因此,必须牢记并在每一次的开发和提交中践行Web性能优化的最佳实践。而恰当的在开发中使用工具,可以帮助我们找到潜在的性能问题,
在开发周期中,没有经过性能检测的代码,天知道面对终端用户时是什么情况。更糟的是,不论好与坏,我们都是没法度量,也没有线索去改进的。如果我们引入如下性能衰退图的话,终端用户就是那个无法忍受糟糕用户体验而发起红色警报的。幸运的话我们可以根据一些忠实的用户反馈,迫使开发者去解决这个问题。当然解决问题的时间可能会持续很久,直到没有人关心,然后用户忍无可忍的放弃掉应用。类似下图:

利用真实用户监测(Real User Measurement, aka RUM),为应用程序提供数据。收集包括如带宽,页面加载时间等数据,进行监测和估计最终用户的体验是什么样的。在性能衰退图下,跟据RUM,可以获得性能问题。即使这样,仍然给了最终用户一个痛苦不愉快的经历。被动的等待问题发现,然后修复,并在下个迭代中发布——这是很多网站目前使用的方式。

RUM结果不理想YSlow一开始是只能通过手动执行,基于一组性能检测规则对页面的进行静态分析,报告检测出的问题。后来开始在真实浏览器中安装YSlow做自动化尝试。
2011后,新的YSlow可以在命令行下利用NodeJS执行。对HAR(HTTP Archieve)文件进行静态分析的。2012年年初,YSlow也可以结合PhantomJS (命令行下没有界面的WebKit浏览器)工作,为一个的URL通过命令行进行分析,并给出结果。 YSlow还专门为PhantomJS还提供了两种新的输出格式:TAP和JUnit 。这两种技术都可以配置设定通过与否的阈值。
基于YSlow为PhantomJS的定制,可以很容易将其整合到持续集成系统中(continous integration, aka CI) 。如果有一个出现性能衰退,就会打破了构建过程,从而避免了潜在的性能问题发布在生产环境中。有效避免最终用户产生很坏的体验。
YSlow的wiki中有解释如何将YSlow和Phantom集成到Jenkins的文章。值得一提的是--threshold参数,会作为最终的性能验收标准的最终配置。

RUM如果是在开发过程中就一直践行着Web性能最佳实践的应用,YSlow的得分就会稳定在A或B中而失去意义。此时的YSlow已经不再能够预警微小的新能衰退了。
此时的YSlow得分,看似令人满意,但并不意味着它的得分就是真实浏览器环境下最终用户体验的得分。所以,接下来的优化将着眼于真实浏览器中的用户体验。通过多次取样真实浏览器下的体验值,然后与上线的性能阈值去比对,来最终确认是否上线。
用WebPagetest来自动化真实浏览器下的性能测试,是个不错的选择,因为他有可供NodeJS调用的API(可参考该文章xmas-gift-webpagetest-api-swiss-army-knife)。

RUM在对新版本(分支)或分支进行WPT测试时,理想情况是有一个单独的与生产环境一样的沙箱,从而让WPT的结果尽可能的与生成环境下最终用户的体检结果一致。
尽可能主动出击,防微杜渐,将Web性能的最佳实践及检测通过YSlow等方式加入到CI中,将性能衰退扼杀在摇篮里,给最终用户创造更好的体验。