词法结构
- unicode以\u为前缀,其后跟随4个十六进制数
- 标识符必须以字母、下划线或$开始,后续字符可以是字母、数字、下划线或$。
类型、值和变量
- js数据类型分为两类:原始类型和对象类型
- 原始类型包括:Number,String和Boolean
- 两个特殊原始值:null和undefined
- js解释器有自己的内存管理机制,可以自动对内存进行垃圾回收(Garbage Collection)。
- js整数范围是 -2^53 ~ 2^53
- 无穷大可以用Infinity表示
- Infinity = Number.POSITIVE_INFINITY = 1/0 = Number.MAX_VALUE + 1
- 非数字值用NaN
- NaN = Number.NaN = 0/0 = Number.MIN_VALUE/2
- -NaN和任何值都不相等,包括自己。要使用x!=x来判断x是否是NaN或者使用isNaN()
- 二进制浮点数表示法不能精确表示类似0.1这样的数字:
var x = .3 - .2;
var y = .2 - .1;
x == y; // false
- String是一组16位值组成的不可变的有序序列
- undefined,null,0,-0,NaN,"" 都会被转换成false,其他值包括对象(数组)会转换成true
- null执行typeof运算,结果返回"object"
- 两个单独的对象永不相等,两个单独的数组永不相等:
var o = {x:1},p = {x:1};
o == p; // => false
o === p; // => false
var a = [], b = [];
a == b; // => false
a === b; // => false
- Javascript类型转换
值 | 转换为 | - | - | - |
---|---|---|---|---|
- | 字符串 | 数字 | 布尔值 | 对象 |
undefined | "undefined" | NaN | false | throws TypeError |
null | "null" | 0 | false | throws TypeError |
true | "true" | 1 | - | new Boolean(true) |
false | "false" | 0 | - | new Boolean(false) |
"" | - | 0 | false | new String("") |
"1.2" | - | 1.2 | true | new String("1.2") |
"sevens" | - | NanN | true | new String("sevens") |
0 | "0" | - | false | new Number(0) |
-0 | "0" | - | false | new Number(-0) |
NaN | "NaN" | - | false | new Number(NaN) |
1 | "1" | - | true | new Number(1) |
{} | 参考3.8.3节 | 参考3.8.3节 | true | |
[] | "" | 0 | true | |
[9] | "9" | 9 | true | |
['a'] | 使用join方法 | NaN | true | |
function(){} | 参考3.8.3节 | NaN | true |
- 关于==相等性判断
null == undefined; // true
"0" == 0; //比较前字符串转换成数字 true
0 == false; //布尔转换成数字 true
"0" == false; //字符串和布尔值都转换成数字 true
- 对日期对象进行转换
````javascript
var now = new Date();
typeof (now + 1); // => string , "+"将日期转换成了字符串
typeof (now - 1); // => Number: "-" 将对象转换成了数字
声明提前
var scope = "global";
function f(){
console.log(scope); // undefined
var scope = "local";
console.log(scope); // local
}
由于局部变量在整个函数体始终都有定义的,就是说,在函数体内局部变量遮盖了同名全局变量。但是!只有在执行到var的时候才会被赋值。因此,上面的代码相当于:
var scope = "global";
function f(){
var scope;
console.log(scope); // undefined
scope = "local";
console.log(scope); // local
}
- 作用域链 *
表达式和运算符
- 2 + null => 2
- 2 + undefined => NaN
- "==" 会将左右两边值如果不存在字符串则先转换数字类型再比较,转换图看上面。
语句
- 如果var语句出现在函数体内,那么它定义的是一个局部变量,作用域是这个函数。如果在顶层代码中使用var语句,它声明的是全局变量,在整个javascript程序中都是可见的。var声明的全局变量是无法通过delete删除的。
- 因为for/in循环中variable的值可以当做赋值表达式的左值,可以利用for..in..快速将一个对象的属性key复制到数组中:
var o = {x:1,y:2,z:3};
var a = [],i = 0;
for(a[i++] in o) ;
- "use strict" 作用在使用指定的作用域
对象
- 模拟继承,通过原型继承创建一个新对象
function inherit(p) {
if (p == null) throw TypeError();
//如果Object.create()存在,则直接使用它
if (Object.create)
return Object.create(p)
//否则进一步检测
var t = typeof p;
if (t !== "object" && t !== 'function')
throw TypeError();
//定义一个空构造函数
function f() {};
//将其原型属性设置为p
f.prototype = p;
return new f();
}
- inherit()函数的其中一个用途就是防止库函数无意间修改那些不受我们控制的对象。不是将对象直接作为参数传入函数,而是将它的继承对象传入函数。
- var len = book && book.subtitle && book.subtitle.length
- 通过in,hasOwnProperty()来判断目标对象是否存在目标属性
- 数据属性的描述符对象的属性有value,writable,enumerable和configurable.
- 复制属性的继承函数
Object.defineProperty(Object.prototype,"extend",
{
writable: true,
enumerable: false,
configurable: true,
value: function (o){
//得到所有自有属性,包括不可枚举属性
var names = Object.getOwnPropertyNames(o);
//遍历
for (var i = 0; i < names.length; i++){
if (names[i] in this) continue;
var desc = Object.getOwnPropertyDescriptor(o,names[i]);
Object.defineProperty(this,names[i],desc);
}
}
}
);
To be Continue..