分析js
js是建立在一些非常优秀的想法和少数非常糟糕的想法之上的
优秀
- 函数
- 弱类型
- 动态对象
- 富有表现力的对象字面量表示法
糟糕的想法
全局变量绑定
尽管JavaScript有缺陷,但它真的很优秀
语法
注释
应该使用//
,而不是/**/
标识符
建议应该由字母开头,允许中间出现数字
和_
应该遵循一定的命名规范
数字
- Js只有一种数字类型。内部表现为64位浮点数,没有分离处整数类型,所以1.0和1一样。可以避免短整型溢出问题。
- 100 = 1e2
NaN
是数值,表示不能产生正常结果的运算结果,它不等于任何值,包括自身,可以用isNaN(number)
判断NaNInfinity
表示大于1.79……e+308的值- 数字拥有方法,包括在
Math对象
之中。
字符串
Unicode
是16位的,所以JS所有字符都是16位的- JS没有字符类型,表示字符就创建一个包含一个字符的字符串就行
- 需要记得的几个转义:
\r
,\n
,\t
- “A” === “\u0041” (\u表示特定字符编码)
- 字符串不可变,一旦创建就无法改变。可以通过
+
等运算创建一个新的字符串 - 包含完全相同字符序列的字符串被认为是完全相同的
'c'+'a'+'t' === 'cat'
语句
js中代码块不会创建新的作用域,因此变量应该被定义在函数的头部,而不是代码块中。
下面的值会被当成假:
- false
- null
- ”
- undefined
- 数字0
- 数字NaN
case
表达式不一定必须是常量for in
会枚举一个对象的所有属性(键名)object.hasOwnProperty()
确定属性是该对象成员的,还是来自原型链for (myvar in obj) { if(obj.hasOwnProperty(myvar)) { …… } }
throw 语句中表达式一般是一个对象字面量,包含
name
和一个message
Javascript 不允许在return 和表达式之间换行 (会自动在尾部添加分号)
Javascript 不允许在break 和表达式之间换行
表达式
运算优先级
运算符优先级:基本就是一元>二元>三元
符号 | 含义 |
---|---|
. [] () | 提取属性调用函数 |
delete new typeof + = ! | 一元 |
| 乘除,求余 |
| 加/减 连接 |
>= <= >< | 不等 |
=== !== | 等式 |
&& | 逻辑与 |
|| | 逻辑或? |
? : | 三元 |
- %
不是传统意义上的取模,而就是取余(其实就是用trunc模式的取模,见我的另一篇文章)
&&
的真实含义:A?B:A,它的特性一般用来避免错误A.b && A.b.c
||
的含义:A?A:B ,它的特性一般用来填充默认值var color = MYAPP.color || ‘#FFF’
字面量
字面量是一个可以快速创建对象
,数组
,函数
的表示法。
- 对象字面量:属性可以是标识符或字符串,这些名字当作字面量名而不是变量名对待,所以对象的属性名在编译时才知道。
- 属性的值就是表达式
对象
介绍
简单数据类型
Javascript的简单数据类型包括数字
、字符串
、布尔值
、null值
、和undefined值
。其他所有的值都是对象
数字
、字符串
、布尔值
看上去是对象,因为它们拥有方法,但是实际上,他们是不可变的
对象
概况
- js中的对象是可变的
键控组合
(keyed collections) 数组
、函数
、正则表达式
都是对象,当然对象也是对象- 对象是属性的容器:
- 属性的名字可以是空字符串在内的任意字符串
- 属性值可以是除undefined值之外的任何值
- 对象是无类型的(class-free)。它对新属性的名字和属性的值没有限制。
- 对象可以包含对象
- js包含一种
原型链
的特性,允许对象继承另一个对象的属性。正确使用能减少对象初始化的时间和内存。
对象字面量
就是包含在{}
之间的零或多个名/值
对。对象字面量可以出现在任何允许表达式出现的地方。
如果属性名是一个合法的
标识符
,则不强制要求使用引号括住属性名:“first-name” 是必须的
first_name 是可选的
检索
要检索里面的值,可以采用[]
,如果是合法的标识符则可以用.
代替。(优先考虑.
,因为它更加紧凑好看)
如果值不存在,会返回
undefined
||
可以用来填充默认值
var status = flight.status || “unknown”
尝试从
undefined
中获取属性会报异常&&
可以用来规避错误
flight.equipment && flight.equipment.mode
更新
对象值可以通过赋值语句更新或者新建
引用
对象通过引用来传递。它们永远不会复制!!!
原型
每个对象都会连接到一个原型对象,并且可以从它中继承属性。所有的对象都连接到Obeject.prototype
新建对象:
if (typeof Object.beget !== 'function'){
Object.create = function(o){
var F = function(){};
F.prototype = o;
return new F();
}
}
- 原型链在更新的使用不起作用(我们改变对象不会影响原型链)
- 如果没有属性,会去查原型,如果原型没有就是去查原型的原型……一直查到
Obejct
,如果还是没有,就报undefined
。这过程称为委托 (这就像一条链一样,所以称为原型链) - 动态:如果在原型中增加一个属性,它立刻对所有基于该原型的对象可见
枚举
for in 可以用来遍历一个对象中的所有
属性名
过滤原型属性,可以用
hasOwnProperty()
if (typeof one_obejct.hasOwnProperty(name)) { …… }
过滤函数,可以用
typeof
if (typeof one_obejct[name] !== 'function') { …… }
for in 是不保证顺序的,如果想保证顺序,可以另创建一个数组包含需要的属性名,用简单的for循环
删除
delete
可以删除对象的属性,不会触及原型链中的任何对象- 删除对象属性后,原型链的属性会透现出来
减少全局污染
最小化使用全局变量的方法之一是为你的应用只创建一个唯一的全局变量:
var MYAPP = {};
把这个MYAPP
作为你的应用容器
MYAPP.person = {
firstName = 'Joe',
lastName= 'Howard'
}
MYAPP.enrollment = function(){
……
}
另一种方法减少全局变量污染的是闭包