JS历史
- 2001年,Douglas Crockford 提出了 JSON 格式,用于取代 XML 格式,进行服务器和网页之间的数据交换。JavaScript 可以原生支持这种格式,不需要额外部署代码。
- 灵活性:过程式 对象式 函数式编程
- 函数式编程,写高并发、异步(事件驱动、非阻塞式)
- 编译运行,接近二进制程序效率
- 作用域、模块、子类型,的实现方式?
当时,接着java的名,给js打广告
这种脚本语言缺少一些关键的功能,比如块级作用域、模块、子类型。
对于其他语言,你需要学习语言的各种功能,而对于 JavaScript,你常常需要学习各种解决问题的模式。而且由于来源多样,从一开始就注定,JavaScript 的编程风格是函数式编程和面向对象编程的一种混合体。
JS大事件
浏览器、js、ecms规范、js版本
css、dhtml、ajax、
浏览器、netscape、mozilla、IE6、
json、网页应用程序(Gmail)、编程框架(dojo)
webkit、ajax(web2.0)、jQuery(函数库)
手机webkit、v8(性能)、nodejs(服务端编程)
模块化开发(npm、backbonejs、requirejs)
单页面应用程序(angular、ember)
Asm(转译js)
react(网页应用是状态机)、rn
es6、webassembly(任何语言可编译成js、在asm基础上的二进制包)
基础
变量的声明和赋值,是分开的两个步骤。
JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。
js区块不构成单独的作用域。
有些开发者习惯将常量写在运算符的左边,这样的话,一旦不小心将相等运算符写成赋值运算符,就会报错,因为常量不能被赋值。
switch比较时不会发生类型转换
初始化表达式(initialize):确定循环变量的初始值,只在循环开始时执行一次。
条件表达式(test):每轮循环开始时,都要执行这个条件表达式,只有值为真,才继续进行循环。
递增表达式(increment):每轮循环的最后一个操作,通常用来递增循环变量。
所有的for循环,都可以改写成whild循环
Break语句用于跳出代码块或循环;
如果存在多重循环,不带参数的break语句和continue语句都只针对最内层循环。
如果break语句后面不适用标签,则只能跳出内层循环,进入下一次的外层循环。
标签也可以用于跳出代码块。
continue语句,跳过当前循环,直接进入下一轮循环。
Instanceof 区分Array 和 Object
undefined “无定义”; null “空”的对象、空值、未赋值
字符串
字符串内部的单个字符能读取,但无法改变和增删。
对于码点在U+10000到U+10FFFF之间的字符,JavaScript 总是认为它们是两个字符(length属性为2)
@
数值
js数值是浮点数,不是精确的值, 0.2 + 0.1 === 0.3 // false
“负向溢出”,返回0
JavaScript 能够表示的数值范围为2 1024到2 -1023(开区间)
Number对象的MAX_VALUE和MIN_VALUE属性,返回可以表示的具体的最大值和最小值。
科学计数法允许字母e或E的后面,跟着一个整数,表示这个数值的指数部分。
JavaScript 会自动将数值转为科学计数法表示,其他情况都采用字面形式直接表示。
(1)小数点前的数字多于21位。
(2)小数点后的零多于5个。
nan“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。也是number类型
0除以0也会得到NaN。
NaN不等于任何值,包括它本身。
除以正零得到+Infinity,除以负零得到-Infinity,这两者是不相等的。
是非0数值除以0,得到Infinity。
0 / 0 // NaN
由于数值正向溢出(overflow)、负向溢出(underflow)和被0除,JavaScript 都不报错,所以单纯的数学运算几乎没有可能抛出错误。
Infinity减去或除以Infinity,得到NaN。
parseTnt 字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。
如果字符串以0x或0X开头,parseInt会将其按照十六进制数解析。
isNaN传入字符串的时候,字符串会被先转成NaN,所以最后返回true,这一点要特别引起注意。
也就是说,isNaN为true的值,有可能不是NaN,而是一个字符串。
出于同样的原因,对于对象和数组,isNaN也返回true。
对于空数组和只有一个数值成员的数组,isNaN返回false。
function myisNan(val) {
return typeof val === 'number' && isNaN(val)
}
判断NaN更可靠的方法是,利用NaN为唯一不等于自身的值的这个特点,进行判断。
function myIsNan(val) {
return val !== val;
}
如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠。
注意,反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错。
// 判断NaN,先判断一下类型
function MyIsNaN(value) {
return typeof value === 'number' && isNaN(value);
}
// 更可靠的方法是,利用NaN为唯一不等于自身的这个特点,进行判断
function myIsNaN(value) {
return value !== value;
}
对象
var obj = {};
obj.foo = 123;
obj.foo // 123
上面代码中,直接对obj对象的foo属性赋值,结果就在运行时创建了foo属性。
JavaScript 允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。
对象变量赋值,是引用
其它原始类型,是值的拷贝
行首是大括号,一律解释为对象。不过,为了避免歧义,最好在大括号前加上圆括号。
如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。
删除一个不存在的属性,delete不报错,而且返回true。因此,不能根据delete命令的结果,认定某个属性是存在的。
只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。
delete命令只能删除对象本身的属性,无法删除继承的属性
in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值)
in运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的
这时,可以使用对象的hasOwnProperty方法判断一下,是否为对象自身的属性。
for...in循环有两个使用注意点。
- 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
- 它不仅遍历对象自身的属性,还遍历继承的属性。