js阶段 总结

1.延迟脚本

HTML 4.01 为 <script> 标签定义了 defer 属性。这个属性的用途是表明脚本在执行时不会影响页

面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,在 <script> 元素中设置

defer 属性,相当于告诉浏览器立即下载,但延迟执行。

<!DOCTYPE html>

<html>

<head>

<title>我的HTML</title>

<script type="text/javascript" defer="defer"src="example1.js"></script>

<script type="text/javascript" defer="defer"src="example2.js"></script>

</head>

<body>

<!-- 这里放内容 -->

</body>

</html>

在这个例子中,虽然我们把<script> 元素放在了文档的<head> 元素中,但其中包含的脚本将延迟

到浏览器遇到</html> 标签后再执行。HTML5 规范要求脚本按照它们出现的先后顺序执行,因此第一

个延迟脚本会先于第二个延迟脚本执行, 而这两个脚本会先于 DOMContentLoaded 事件 (详见第 13 章)

执行。在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在 DOMContentLoaded 事件触发

前执行,因此最好只包含一个延迟脚本。

前面提到过, defer 属性只适用于外部脚本文件。这一点在 HTML5 中已经明确规定,因此支持

HTML5 的实现会忽略给嵌入脚本设置的 defer 属性。IE4~IE7 还支持对嵌入脚本的 defer 属性,但

IE8 及之后版本则完全支持 HTML5 规定的行为。

2.异步脚本

HTML5 为 <script> 元素定义了 async 属性。这个属性与 defer 属性类似,都用于改变处理脚本的行为。同样与 defer 类似, async 只适用于外部脚本文件, 并告诉浏览器立即下载文件。但与 defer

不同的是,标记为 async的脚本并不保证按照指定它们的先后顺序执行。例如:

<!DOCTYPE html>

<html>

<head>

<title>Example HTML Page</title>

<script type="text/javascript" asyncsrc="example1.js"></script>

<script type="text/javascript" asyncsrc="example2.js"></script>

</head>

<body>

<!-- 这里放内容 -->

</body>

</html>

在以上代码中,第二个脚本文件可能会在第一个脚本文件之前执行。因此,确保两者之间互不依赖

非常重要。指定 async 属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。

为此,建议异步脚本不要在加载期间修改 DOM。

异步脚本一定会在页面的load 事件前执行,但可能会在DOMContentLoaded 事件触发之前或之

后执行。支持异步脚本的浏览器有 Firefox 3.6、Safari 5 和 Chrome。

3. HTML 中,有特殊的规则用以确定 <script> 元素中的哪些内容可以被解析,但这些特殊的规则

XHTML 中不适用。这里比较语句 a < b 中的小于号(<)在 XHTML中将被当作开始一个新标签来

解析。但是作为标签来讲,小于号后面不能跟空格,因此就会导致语法错误。

——————————

① HTML5 正快速地被前端开发人员采用,建议读者在学习和开发中遵循 HTML5 标准,本节内容可以跳过。避免在 XHTML 中出现类似语法错误的方法有两个。一是用相应的 HTML 实体( &lt; )替换代码

中所有的小于号(<) ,替换后的代码类似如下所示:

<scripttype="text/javascript">

function compare(a, b) {

if (a &lt; b) {

alert("A is less than B");

} else if (a > b) {

alert("A is greater than B");

} else {

alert("A is equal to B");

}

}

</script>

虽然这样可以让代码在XHTML 中正常运行,但却导致代码不好理解了。为此,我们可以考虑采用

另一个方法。

保证让相同代码在 XHTML中正常运行的第二个方法,就是用一个 CData 片段来包含 JavaScript 代

码。在 XHTML(XML)中,CData 片段是文档中的一个特殊区域,这个区域中可以包含不需要解析的

任意格式的文本内容。因此,在CData 片段中就可以使用任意字符——小于号当然也没有问题,而且不

会导致语法错误。引入CData 片段后的JavaScript 代码块如下所示:

<scripttype="text/javascript"><![CDATA[

function compare(a, b) {

if (a < b) {

alert("A is less than B");

} else if (a > b) {

alert("A is greater than B");

} else {

alert("A is equal to B");

}

}

]]></script>

在兼容 XHTML 的浏览器中,这个方法可以解决问题。但实际上,还有不少浏览器不兼容XHTML,

因而不支持 CData 片段。怎么办呢?再使用 JavaScript 注释将 CData 标记注释掉就可以了:

<scripttype="text/javascript">

//<![CDATA[

function compare(a, b) {

if (a < b) {

alert("A is less than B");

} else if (a > b) {

alert("A is greater than B");

} else {

alert("A is equal to B");

}

}

//]]>

</script>

这种格式在所有现代浏览器中都可以正常使用。虽然有几分 hack 的味道,但它能通过XHTML 验

证,而且对 XHTML 之前的浏览器也会平稳退化。

小结

JavaScript 插入到 HTML 页面中要使用 <script> 元素。使用这个元素可以把 JavaScript 嵌入到

HTML页面中,让脚本与标记混合在一起;也可以包含外部的 JavaScript文件。而我们需要注意的地方有:

  在包含外部 JavaScript 文件时,必须将src 属性设置为指向相应文件的 URL。而这个文件既可

以是与包含它的页面位于同一个服务器上的文件,也可以是其他任何域中的文件。

  所有 <script> 元素都会按照它们在页面中出现的先后顺序依次被解析。在不使用 defer

async 属性的情况下,只有在解析完前面 <script> 元素中的代码之后,才会开始解析后面

<script> 元素中的代码。

  由于浏览器会先解析完不使用 defer 属性的<script> 元素中的代码,然后再解析后面的内容,

所以一般应该把 <script> 元素放在页面最后,即主要内容后面,</body> 标签前面。

  使用 defer 属性可以让脚本在文档完全呈现之后再执行。延迟脚本总是按照指定它们的顺序执行。

  使用 async 属性可以表示当前脚本不必等待其他脚本,也不必阻塞文档呈现。不能保证异步脚

本按照它们在页面中出现的顺序执行。

另外,使用 <noscript> 元素可以指定在不支持脚本的浏览器中显示的替代内容。但在启用了脚本

的情况下,浏览器不会显示 <noscript> 元素中的任何内容

 

 

 

5. typeof 操作符

鉴于 ECMAScript 是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof 就

是负责提供这方面信息的操作符。对一个值使用 typeof 操作符可能返回下列某个字符串:

 "undefined" ——如果这个值未定义;

 "boolean" ——如果这个值是布尔值;

 "string" ——如果这个值是字符串;

 "number" ——如果这个值是数值;

 "object" ——如果这个值是对象或 null ;

 "function" ——如果这个值是函数。

下面是几个使用 typeof操作符的例子:

var message = "some string";

alert(typeof message); //"string"

alert(typeof(message)); //"string"

alert(typeof 95); // "number"

TypeofExample01.htm

这几个例子说明, typeof操作符的操作数可以是变量(message ) ,也可以是数值字面量。注意,

typeof 是一个操作符而不是函数,因此例子中的圆括号尽管可以使用,但不是必需的。

有些时候, typeof 操作符会返回一些令人迷惑但技术上却正确的值。比如,调用 typeofnull

会返回"object" ,因为特殊值 null 被认为是一个空的对象引用。Safari5 及之前版本、Chrome 7及之

前版本在对正则表达式调用typeof 操作符时会返回"function" ,而其他浏览器在这种情况下会返回

"object" 。

6. 实际上,如果指定了 16 作为第二个参数,字符串可以不带前面的 "0x" ,如下所示

var num1 = parseInt("AF", 16);//175

var num2 = parseInt("AF"); //NaN

这个例子中的第一个转换成功了,而第二个则失败了。差别在于第一个转换传入了基数,明确告诉

parseInt() 要解析一个十六进制格式的字符串;而第二个转换发现第一个字符不是数字字符,因此就

自动终止了。

指定基数会影响到转换的输出结果。例如:

var num1 = parseInt("10", 2); //2(按二进制解析)

var num2 = parseInt("10", 8); //8(按八进制解析)

var num3 = parseInt("10", 10);//10 (按十进制解析)

var num4 = parseInt("10", 16);//16 (按十六进制解析)

NumberExample07.htm

不指定基数意味着让parseInt() 决定如何解析输入的字符串,因此为了避免错误的解析,我们建议无论在什么情况下都明确指定基数。

parseInt() 函数类似, parseFloat() 也是从第一个字符(位置 0)开始解析每个字符。而且

也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第

一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。举例来说,

"22.34.5"将会被转换为 22.34。

除了第一个小数点有效之外,parseFloat() 与 parseInt() 的第二个区别在于它始终都会忽略前导

的零。parseFloat() 可以识别前面讨论过的所有浮点数值格式,也包括十进制整数格式。但十六进制格

式的字符串则始终会被转换成0。由于parseFloat() 只解析十进制值,因此它没有用第二个参数指定基

数的用法。最后还要注意一点:如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后

都是零) , parseFloat() 会返回整数。以下是使用 parseFloat() 转换数值的几个典型示例。

var num1 =parseFloat("1234blue"); //1234 (整数)

var num2 = parseFloat("0xA"); //0

var num3 = parseFloat("22.5");//22.5

var num4 = parseFloat("22.34.5");//22.34

var num5 = parseFloat("0908.5");//908.5

var num6 = parseFloat("3.125e7");//31250000

7. toString() 可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格

式表示的字符串值。下面给出几个例子:

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"

在不知道要转换的值是不是 null undefined 的情况下,还可以使用转型函数 String() 这个

函数能够将任何类型的值转换为字符串。 String() 函数遵循下列转换规则:

  如果值有 toString() 方法,则调用该方法(没有参数)并返回相应的结果;

  如果值是 null ,则返回 "null" ;

  如果值是 undefined ,则返回 "undefined" 。

下面再看几个例子:

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"

8.

var o = new Object(); 推荐

var o = new Object; // 有效,但不推荐省略圆括号

Object 的每个实例都具有下列属性和方法。

constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)

就是 Object() 。

hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例

的原型中)是否存在。其中,作为参数的属性名( propertyName 必须以字符串形式指定(例

如: o.hasOwnProperty("name")

isPrototypeOf(object) :用于检查传入的对象是否是传入对象的原型(第 5 章将讨论原

型) 。

propertyIsEnumerable(propertyName) :用于检查给定的属性是否能够使用 for-in 语句

(本章后面将会讨论)来枚举。与 hasOwnProperty() 方法一样,作为参数的属性名必须以字符

串形式指定。

toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。

toString() :返回对象的字符串表示。

valueOf() :返回对象的字符串、数值或布尔值表示。通常与 toString() 方法的返回值

相同

9.

var gae = 1;

var haha = gae++;  // 先赋值 ,后自加

console.log(haha);  //  1

var gae = 1;

gae++;

console.log(gae) //  2

var num1 = 2;

var num2 = 20;

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

var num4 = num1 + num2;// 等于 21

 

var num1 = 2;

var num2 = 20;

var num3 = num1-- + num2;//  等于 22       先参与运算后自减

var num4 = num1 + num2;// 等于 21

 

var num1 = true;  //在应用于布尔值 true 时,先将其转换为1 再执行加减 1 的操作。布尔值变量变成数值变量

num1++;

console.log(num1)   //  2

 

 

var s1 = "2";

var s2 = "z";

var b = false;

var f = 1.1;

在应用于对象时,先调用对象的 valueOf() 方法(第 5 章将详细讨论)以取得一个可供操作的

值。然后对该值应用前述规则。如果结果是 NaN ,则在调用 toString() 方法后再应用前述规

则。对象变量变成数值变量

var o = {

valueOf: function() {

return -1;

}

};

s1++; // 值变成数值 3

s2++; // 值变成 NaN

b++; // 值变成数值 1

f--; // 值变成0.10000000000000009(由于浮点舍入错误所致)

o--; // 值变成数值-2

 

+ 一元操作符

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

 

- 一元操作符

 

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

 

 

 

 

 

 

 

二进制转换

 

 

 

 

alert(!false); // true

alert(!"blue");// false

alert(!0); // true

alert(!NaN);// true

alert(!""); //true

alert(!12345); // false

 

alert(!!"blue");//true

alert(!!0); //false

alert(!!NaN);//false

alert(!!"");//false

alert(!!12345); //true

 

&&     要是true 都是true   如果都是false 都是false

var found = true;

var result = (found&& someUndefinedVariable); // 这里会发生错误

alert(result); // 这一行不会执行

LogicalAndExample01.htm

在上面的代码中,当执行逻辑与操作时会发生错误,因为变量 someUndefinedVariable 没有声

明。由于变量 found 的值是 true ,所以逻辑与操作符会继续对变量 someUndefinedVariable 求值。

someUndefinedVariable 尚未定义,因此就会导致错误。这说明不能在逻辑与操作中使用未定义

的值。如果像下面这个例中一样,将 found 的值设置为 false ,就不会发生错误了:

var found = false;

var result = (found&& someUndefinedVariable); // 不会发生错误

alert(result); // 会执行("false"

 

 

 

var found = false;

var result = (found&& someUndefinedVariable); // 不会发生错误

if (found &&someUndefinedVariable) {  // 这里 false

    alert(result);  // 不会执行

}

 

alert(result); //false  这里会执行

 

 

逻辑或操作符由两个竖线符号( || )表示,有两个操作数

 

var found = true;

var result = (found ||someUndefinedVariable); // 不会发生错误

alert(result); // 会执行("true"

 

3.6.2 do-while 语句

do-while 语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件。

换句话说,在对条件表达式求值之前,循环体内的代码至少会被执行一次。以下是 do-while 语句的

语法:

do {

statement

} while (expression);

下面是一个示例:

var i = 0;

do {

i += 2;

} while (i < 10);

alert(i);

 

 

while 语句属于前测试循环语句,也就是说,在循环体内的代码被执行之前,就会对出口条件求值。

因此,循环体内的代码有可能永远不会被执行。以下是 while 语句的语法:

while(expression)statement

下面是一个示例:

var i = 0;

while (i < 10) {

i += 2;

}

 

 

3.6.5  for-in语句

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。以下是 for-in 语句的语法:

for (property inexpression) statement

下面是一个示例:

for (var propName inwindow) {

document.write(propName);

}

 

 

3.6.6  label 语句

使用 label 语句可以在代码中添加标签,以便将来使用。以下是 label 语句的语法:

label: statement

下面是一个示例:

start: for (var i=0; i< count; i++) {

alert(i);

}

这个例子中定义的 start 标签可以在将来由 break continue 语句引用。加标签的语句一般都

要与 for 语句等循环语句配合使用。

 

 

3.6.7  break continue 语句

break continue 语句用于在循环中精确地控制代码的执行。其中, break 语句会立即退出循环,

强制继续执行循环后面的语句。而 continue 语句虽然也是立即退出循环,但退出循环后会从循环的顶

部继续执行。请看下面的例子:

var num = 0;

for (var i=1; i < 10;i++) {

if (i % 5 == 0) {

break;

}

num++;

}

alert(num); //4

 

3.6.9  switch语句

switch 语句与 if语句的关系最为密切,而且也是在其他语言中普遍使用的一种流控制语句。

ECMAScript switch 语句的语法与其他基于 C 的语言非常接近,如下所示:

switch (expression) {

case value: statement

break;

case value: statement

break;

case value: statement

break;

case value: statement

break;

default: statement

}

 

 

 

switch (i) {

case 25:

/*  合并两种情形 */

case 35:

alert("25 or35");

break;

case 45:

alert("45");

break;

default:

alert("Other");

}

猜你喜欢

转载自blog.csdn.net/weixin_37806077/article/details/80248763