JavaScript高级程序设计(第三版)①

1 JavaScript实现

 一个完整的JavaScript实现应该由三部分组成:ECMAScriptDOMBOM

ECMAScript(核心):
语法
类型
语句
关键字
保留字
操作符
对象
DOM(文档对象模型):
 DOM把整个页面映射成一个多层节点结构。HTML或XML页面中的每个组成部分都是某种类型的节点,这些节点又包含这不同类型的数据。借助DOM提供的API,开发人员可以轻松自如地删除、添加、替换或修改任何节点,API类型有以下几种:
DOM视图(DOM Views):定义了跟踪不同文档(例如、应用CSS之前和之后的文档)视图的接口;
DOM事件(DOM Events):定义了事件和事件处理的接口;
DOM样式(DOM Style):定义了基于CSS为元素应用样式的接口;
 ...
BOM(浏览器对象模型):
 开发人员使用BOM可以控制浏览器显示的页面以外的部分。一般而言,BOM只处理浏览器窗口和框架;但人们习惯上也把所有针对JS扩展算作BOM的一部分。如:
弹出新浏览器窗口的功能;
移动、缩放和关闭浏览器窗口的功能;
提供浏览器详细信息的navigator对象;
提供浏览器所加载页面的详细信息的location对象;
提供用户显示器分辨率详细信息的screen对象;
对cookies的支持;
像XMLHttpRequest 和 IE 的ActiveXObject这样的自定义对象。

2 在HTML中使用JavaScript

 向HTML页面中插入JS的主要方法,就是使用,HTML4.01为不需要再写额外代码,写了也不执行,而且src还可包含外部域的JS文件,如http://www.abc.com/foo.js
type:可选。
 现在一般把JS引用放在标签中,放在页面代码的后面。

2.1 嵌入代码与外部文件

 推荐尽可能使用外部文件来包含JS代码:
可维护性;
可缓存,浏览器能够根据具体的设置缓存链接的所有外部JS文件,如果有两个页面都使用同一个JS文件,那么只需要下载一次。 ★

3 文档模式

 使用文档类型切换实现。

4 语法

区分大小写;
标识符最好使用驼峰命名法;
严格模式;
语句结束时最好带分号,如果省略,则由解析器确定语句的结尾;
{ }最好不要省略;
关键字与保留字不可以用作变量、标签或者函数名;
变量:ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。
使用var操作符定义的变量将成为定义该变量的作用域中的局部变量

function test(){
    var message = "hi"; // 局部变量
}
test();
alert(message); // 错误!
function test(){
    message = "hi"; // 全局变量 
}
test();
alert(message); // "hi"

 也可以这样连续定义多个变量,用逗号隔开:

var message = "hi",
    found = false,
    age = 29;

5 数据类型

NaN,在ECMAScript中,任何数值除于0会返回NaN,和其他语言不同;
string类型中的字符字面量;
ECMAScript中的字符串是不可变的,要改变某个变量保存的字符串,首先就要创建新的字符串,再在内存里销毁原来的字符串;
转换成字符串:

var age = 11;
var ageAsString = age.toString(); // 字符串11
var found = true;
var foundAsString = found.toString(); // 字符串true

 还可以带参去转换成不同进制的字符串:

var num = 10;
alert(num.toString());  // 10
alert(num.toString(2)); // 1010
alert(num.toString(8)); // 12
alert(num.toString(10)); // 10
alert(num.toString(16)); // a

 其他:

var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
alert(String(value1)); // 10
alert(String(value2)); // true
alert(String(value3)); // null
alert(String(value4)); // undefined

6 操作符

--a ++a(一元递减递增操作符):

var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2; // 等于21 
var num4 = num1 + num2; // 等于21

 执行前置型递减递增时,变量的值都是在语句被求值前改变的;而后置型递增或递减a-- a++,不会立即影响到当前包含它们的语句求值,但实际上a已经发生增或减操作:

var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2; // 等于22 
var num4 = num1 + num2; // 等于21
var num5 = (num1--) + num1; // 等于1 + 0

 这四种递减递增操作符,不仅对整数有效,对其他的数据类型也有效:

var s1 = "2";
var s2 = "z";
var b = false;
var f = 1. 1;
var o = {
    valueOf: function() {
        return -1;
    }
};
s1++; // 值变成数值3 
s2++; // 值变成NaN 
b++; // 值变成数值1 
f--; // 值变成0.10000000000000009(由于浮点舍入错误所致) 
o--; // 值变成数值-2

-a +a(一元加和减操作符):
 对非数值应用一元加操作符时,该操作符会像Number()转型函数一样对这个值执行转换;如果是对象的话,则会先调用它们的valueOf()和(或)toString()方法,再转换得到的值:

var s1 = "01";
var s2 = "1. 1";
var s3 = "z";
var b = false;
var f = 1. 1;
var o = {
    valueOf: function() {
        return -1;
    }
};
s1 = +s1; // 值变成数值1
s2 = +s2; // 值变成数值1.1
s3 = +s3; // 值变成NaN 
b = +b; // 值变成数值0
f = +f; // 值未变,仍然是1.1
o = +o; // 值变成数值-1

 对非数值应用一元减操作符时,规则和加法是一样的,只是会把得到的数值最后再转化一次,转成负数。

③ 位操作符: ★
1> 计算一个负数的反码 -
 JS虽然用的是IEEE-754 64位格式存储,但实际操作时,是把64位转为32位,执行操作后,再转回64位。计算-18的二进制补码(负数存储格式是二进制补码)时,先求出18的二进制码10010(五个有效位),将0替换成1、1为0;再将得到的二进制反码加1,成功得到111111111111111111111111111101110。

2> 按位非(NOT) ~

var num1 = 25; // 二进制 
00000000000000000000000000011001
var num2 = ~num1; // 二进制 
11111111111111111111111111100110
alert(num2); // -26

 求操作数的负值再减去1,也可以得到相同结果:

var num1 = 25;
var num2 = -num1 - 1;
alert(num2); // "-26"

3> 按位与(AND) &
 使用&操作两个数值时,会将两个数值的每一位对齐,然后根据下表的操作,对相同位置上的两个数执行and操作:

JavaScript高级程序设计(第三版)①_第1张图片

 只有都是1才返回1:

var result = 25 & 3;
alert(result); //1

 因为25和3的对应的32个位置,只有最后一位上下都是1,其余上下执行and操作都得0。

4> 按位或(OR) |
 规则同&

JavaScript高级程序设计(第三版)①_第2张图片

5> 按位异或(XOR) ^
 规则同&

JavaScript高级程序设计(第三版)①_第3张图片

6> 左移操作符 <<
 将数值所有位整体向左移,右侧多出的5个空格用0来填,2 << 5等于64。

7> 有符号的右移操作符 >>
 与左移正好相反,64 >> 5等于2,会用符号位的值填补空格,原本是1就用1,是0用0。

8> 无符号的右移操作符 >>>
 与>>的区别是,>>>不会用符号位的值填补空格,而是用0,这样的话,如果转化的是负数,出来的结果区别会很大。

④ 布尔操作符: ★
1> !(NOT)
 转化任意值,再求反:

alert(!false); // true 
alert(!"blue"); // false 
alert(!0); // true 
alert(!NaN); // true 
alert(!""); // true 
alert(!12345); // false

2> &&(AND)

var result = true && false;

 需要两个值,不会转化值,除了数值和bool值,但如果第一个值是false,那么第二个值是什么都不重要,不管也不去求值,直接返回false,即便是错误的,&&是个短路操作符
 另外,如果有一个数不是布尔值,那&&不只是能返回布尔值,它遵循以下规则:
 如果第一个数是对象,则返回第二个数;
 如果第二个数是对象,那么只有第一个数的求值结果为true的情况下才会返回该对象;
 如果两个数都是对象,则返回第二个数;
 如果有一个数是null,则返回null
 如果有一个数是NaN,则返回NaN
 如果有一个数是undefined,则返回undefined

3> ||(OR) ★
||也是个短路操作符,第一个值是true就不管了,也同样不只返回布尔值:
 如果第一个数是对象,则返回第一个数;
 如果第一个数的求值结果为false,则返回第二个数;
 如果两个数都是对象,则返回第一个数;
 如果两个数都是null,则返回null
 如果两个数都是NaN,则返回null
 如果两个数都是undefined,则返回undefined
可以利用这些特性来赋值:

var preferredObject;
var backupObject = '2';
var myObject = preferredObject || backupObject;

⑤ 乘性操作符 *
*如果乘的不是数值,会调用Number()将其转为数值;/除法同乘法相似;求模(余数)用%

var result = 26 % 5; // 等于 1

⑥ 加性操作符 +
+分三种情况:数值相加、字符串相加(字符串拼接)、其余的(对象、数值、布尔调用toString()undefinednull调用String());

var num1 = 5;
var num2 = 10;
var message = "The sum of 5 and 10 is " + (num1 + num2);
alert(message); //"The sum of 5 and 10 is 15"

 不加括号会输出...510;
-的话分两种情况:数值相减、其余的(数值、布尔、undefinednull调用Number(),对象用valueOf())。

⑦ 关系操作符 <><=>=
<><=>=,会返回布尔值,其规则:
 如果两个操作数都是数值,则执行数值比较;
 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值;
 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较;
 如果一个操作数是对象,则调用这个对象的valueOf()方法,用得到的结果按照前面的规则执行比较;
 如果对象没有valueOf()方法,则调用toString()方法,并用得到的结果根据前面的规则执行比较;
 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较;
 任何操作数与NaN进行关系比较,结果都是false

⑧ 条件操作符 ?: ★

variable = boolean_ expression ? true_ value : false_ value;

boolean_ expression求值,若为truevariabletrue_value;若为falsevariabletrue_value

⑨ 赋值操作符 =

var num = 10;
num = num + 10;

 可简化为:

var num = 10;
num += 10;

 这样的简化还有*=/=%=<<=

⑩ 逗号操作符 ,
 简化操作:

var num1 = 1,
    num2 = 2,
    num3 = 3;

 总返回表达式最后一项:

var num = (5, 1, 4, 8, 0); // num 的值为 0

 这玩意不是(x,y)...

优先级从高到底
()的优先级最高;
一元运算符,++ -- !
算数运算符,先* / %+ -
关系运算符,> >= < <=
相等运算符,== != === !==
逻辑运算符,先&&||

你可能感兴趣的:(JavaScript高级程序设计(第三版)①)