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的主要方法,就是使用<script></script>,HTML4.01为<script>定义了以下六个属性
async:可选;立即下载脚本,只对外部脚本有效;
charset:可选;
defer:可选;立即下载,但延迟执行,只对外部脚本有效,表示脚本可以延迟到文档完全被解析和显示之后再执行;
language:已废弃;
src:可选。表示包含要执行代码的外部文件,注意带src<script></script>不需要再写额外代码,写了也不执行,而且src还可包含外部域的JS文件,如http://www.abc.com/foo.js
type:可选。
 现在一般把JS引用放在<body>标签中,放在页面代码的后面。

2.1 嵌入代码与外部文件

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

3 文档模式

 使用文档类型<!DOCTYPE html>切换实现。

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操作:

 只有都是1才返回1:

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

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

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

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

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)...

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容