###JavaScript 语法
- 区分大小写
- 标示符(名字):第一个字符必须是字母、下划线、美元符号,不能是保留字
- 注释 //我是行注释 /我是块注释/
- 严格模式:严格模式是为 JavaScript 定义了一种不同的解析和执行模型。使用:
'use strict'- 语句:以分号结尾,必须写分号,这样会避免错误,并提高解析器解析性能,解析器不用考虑插入分号位置。 不能随意节省大括号,代码块一定要用
{}括起来。- 保留字和关键字:都不许使用,都是已有或者可能成为控制语句的关键字的。
- 变量:松散类型,声明变量名但不赋值会是
undefined,声明时使用var关键字, 省略var该变量就是变成全局变量了。声明后的变量也会有作用域,完整声明:var me = "karyn";, 多个变量连续声明可以用','隔开如:var me = "karyn", she = "wenyang";
###数据类型
#####基本数据类型:Undefined、Null、Boolean、Number、String。
Undefined:对于以声明但没有赋值的变量就会是undefined。未声明的变量只能用typeof,
在非严格模式下使用delete为声明的变量也不会报错。
Null:空指针,typeof null === "object",null == undefined这个是 true。
Boolean:布尔类型只有true和false,区分大小写;Boolean(NaN) === false, Boolean(null) === false。
Number:
0.1 + 0.2 != 0.3isFinite()用于检验数字类型的参数是否为无限NaN == NaN //false,isNaN(null) //false,这两个判断一定要注意。Number()一般情况下会调用valueOf(),再调用toString(),并且在判断的时候会有一些死规则。parseInt(num,进制数),在使用parseInt的时候一定要指明第二个参数,如果不指明, 浏览器在面对一些特殊数字的时候容易转错。但是不能转为小数。parseFloat(num),可以转为小数,但只能转为10进制。
String:
'\u03a3'.length //1,一些字符字面量在进行计算长度的时候var name = "karyn"; name = name + "song",这个过程是首先创造能容纳5个字符的字符串,并把"karyn"填充进去,将这个值赋给name, 第二步是创造一个能容纳9个字符的字符串,并把"karyn"和"song"填充进去,将原来的"name"销毁,并生成新的"name"。toString(),null和undefined没有此方法,但可以通过String(null)和String(undefined)
#####复杂数据类型:Object 这种类型是该语言所有对象的基础类型,比较复杂,后面会详述。
###判断值的类型
typeof():只能判断基础类型,复杂数据类型都会返回 "object"。所以这种判断方式显然不好。
下面写了一个typeof结合另一个方法的识别方式。
function typeChecking(arg){
var type = typeof(arg);
if(type !== "object"){
return type;
}else{
return Object.prototype.toString.call(arg).slice(8,-1);
}
}
###操作符
true && null //null && 运算中有一个参数为 null 即为 null(null、undefined、NaN)
-0 + -0 //-0
"23" < "3" //true ("2"的字符编码是50,"3"的字符编码是51)
NaN < 3 || NaN >= 3 //false
###关系操作符
- 如果一个操作数是布尔值,则先将其转为数值,然后再进行比较
- 对象在做比较时,先调用对象的
valueOf()方法,如果没有这个方法则调用toString()方法。null == undefined //trueNaN不等于任何数
###变量
- 给基本类型数据增加属性没用。
var name = "karyn"; name.age = 11; //name.age === undefinedvar name1 = "karyn",name2 = name1,基本类型的值复制之后name1和name2之间不会相互影响。- 上面的声明对于引用类型的值就会相互影响,对于这两个变量来讲其实都是存的指针。指针指向存储堆中的一个对象。
- 在函数内部重写传进去的参数,这种对于引用值的引用就是一个局部对象。这个局部对象不会对原有的值有影响,且在函数执行完后会被销毁。
###作用域的影响:
var n = 0;
function a(){
var n = 1; //没有这句话会得到完全不同的结果
function b(){
console.log(++n);
}
return b;
}
a()();
console.log(n);
###垃圾回收:
找出那些不再使用的变量,然后释放其占用的内存,这是会在一定的周期时间做的。内存回收策略:标记清除、引用计数。
标记清除:变量再被使用时我们对次变量进行标记类似”进入环境”,不再使用时标记”离开环境”,最后在一定周期后释放。
引用计数:当使用到该变量时,将这个变量的引用次数+1,当这个值取其他值时就减1,同时在一定周期时间后释放。
在进行垃圾回收的时候遇到循环引用的时候会导致内存泄露,最好的方式就是先将变量手动的置为 null,将对象设置为 null 时, 就切断了与之前所有的引用值之间的联系。
性能问题:IE的垃圾收集器是根据内存分配量运行的,具体一点说就是256个变量,4096个对象字面量和数组元素或64KB的字符串, 达到以上任何一个临界值都会运行,如果一个脚本里长期有这么多变量常驻,则垃圾机制会一直运行,这样会带来非常大的性能问题, IE7重写了这一机制,在达到快临界值时,将这个临界值翻倍,如果垃圾被回收至85%时又会回到默认值。以此提高性能。
手动调用内存清理机制:IE:window.CollectGarbage(),Opeara 7window.opera.collect()。
解除引用:一旦数据不再引用,将其值手动的设置为null,主要适用于全局对象和全局变量,
解除引用并不意味着立刻就会被垃圾回收,只是让值脱离了执行环境以便下次被回收。
局部变量会在离开执行环境时自动解除引用。
总结:
- 基本类型值在内存中占据固定大小的空间,因此会被保存在栈内存中。
- 从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本。 引用类型的值是对象,保存在堆内存中。 包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。 从一个引用类型的值复制给另一个引用类型的值,实际上复制的是指针,两个变量都指向同一个对象。 结合
typeof和Object.prototype.toString.call()检验值的类型。