一、基本介绍与发展
-
网页的组成:
-
JavaScript的组成:ECMAScript、BOM、DOM
- ECMAScript是一个标准。它规定了语法、类型、语句、关键字、保留子、操作符、对象。(相当于法律)
- BOM(浏览器对象模型):可以访问浏览器窗口的浏览器对象模型,对浏览器窗口进行操作。
- DOM(文档对象类型):DOM把整个页面映射成一个多层节点结构。HTML页面组成都是某种类型的节点,这些节点又包含着不同类型的数据
-
Javascript和HTML5的关系
HTML5是一种新的技术,就目前而言,我们所知的HTML5都是一些标签,但是有了JS之后,这些标签深层的扩展功能才得以实现。
比如video标签,我们对其理解为一个简单的标签,但实际上,video标签还有更深层次的扩展功能。
二、如何编写及运行JS
- JS是一种脚本语言,也需要依托于html的执行,可以有三种编写方式:行内(内联),内部,外部。
-
内联:以html标签的属性存在
<button onclick="alert('hello')"></button> 或 <button onclick="fn()"></button> <script> function fn(){ alert("world") } </script>
- 不推荐使用,结构和样式要分离
- 需要行为触发,无法自动执行
- 不方便进行多个功能模块的复用和维护
-
内部:写在html文件内的script标签内
<script> document.querySelector(".box").onclick = function(){ alert("js1"); } // 或 alert('js2') </script>
- 可以不通过行为触发,会自动执行
- 结构和行为没有完全分离,不方便多个页面模块之间功能的复用和维护
-
外部:写在js文件内,然后在html文件中使用script的src引入
// js文件 alert("hello world");
<script src="index.js"></script>
- 可以不通过行为触发,会自动执行
- 结构和行为分离,方便功能的复用和维护
- 推荐使用
src 属性链接的是 JavaScript 文件,文件的扩展名为 .js,如 index.js
-
错误写法:内部和外部,使用一个script标签,不允许!!!
<script src="路径"> //在script标签内写js脚本 </script>
-
执行方式和执行顺序:
- 内联,只能通过行为触发,不触发就不执行
- 内部和外部,先写的先执行
- script标签可以放在任何位置,但是一般放在body的最后 或 结束标签后,也有可能会放在head的最后
三、如何将信息呈现给用户
-
向页面中打印内容:
document.write("这是一些文本内容");
可以直接解析标签:
document.write("<strong>加粗的内容</strong>");
转义字符:
// < ==== < // > ==== > document.write("<strong>这是一些加粗的内容</strong>");
document.write
会将要打印的内容强行转成字符,这会导致某些数据类型并不能直接查看到内容(如Object,Function)
document.write
还非常注重执行时机。页面完全加载结束之前执行,为正常想页面打印内容;页面加载结束后执行,则会覆盖整个document -
将信息打印到浏览器的控制台
console.log("hello world")
console
是个浏览器对象,除了log
之外还有很多其他打印信息的方法
console
会保持原有数据类型打印,不会对数据进行强制转换
console
可以接收多个打印数据,之间使用,
隔开
console
可以根据数据的引用地址,看到将来的异步数据,这需要你对程序过程有所了解,否则你可能不太好判断当前数据是不是这一刻的数据
console
打印的位置为浏览器的控制台,这里不是DOM的范围,所以无法解析标签,并且不会对DOM造成任何影响 -
弹出框显示信息
alert("hello")
alert
会将信息显示在浏览器的弹出框中
alert
会将要打印的内容强行转成字符,这会导致某些数据类型并不能直接查看到内容(如Object,Function)
alert
同时可以停止浏览器加载代码
浏览器解析代码的顺序(从上到下,从左到右)
四、数据类型及检测方式
- 数据类型:所有需要计算机处理的信息都可以称为数据,数据是放在计算机的内存中的,由于计算机只能识别0和1,所以需要对不同类型的数据进行转义,转义的结果会导致所需空间不同,为了方便计算机储存数据,JS中划分了多种数据类型:
- 字符型(string):所有使用引号包裹的数据,单
'
,双"
,反`。表示了数据最原始的格式,是元数据的一种。 - 数值型(number):表示数字,包括:
0,1,2,3,4,5,6,7,8,9,NaN
。 - 布尔型(boolean):表示真或假,包括:
true
,false
。 - 对象型(object):表示数据的打包,多个数据的集合。
- 数据的有序集合使用中括号
[]
包裹,表示array对象,如[值1,值2,值3]
- 数据的无序集合使用花括号
{}
包裹,表示object对象,如:{键1:值1,键2:值2}
- 数据的有序集合使用中括号
- 函数型(function):表示实现了某个功能的代码段的打包。一般使用
function(){}
表示。 - undefined(undefined):一种特殊类型,当变量被声明,但未赋值时,类型为
undefined
。 - null(object):空指向,只有一个指针,但是没有指向任何数据,会被typeof检测出object
- symbol(symbol):类字符数据,用来表示字典量状态,ES6新增数据类型 *
- 字符型(string):所有使用引号包裹的数据,单
- 数据类型的检测 - 关键字:
typeof
typeof 要检测的数据
或typeof(要检测的数据)
- 执行结果就是数据对应类型的单词标志,标志自身以字符型数据展示
typeof
检测null
时得到的是object
,所以typeof
无法区分null
*
五、变量的概念和使用
-
变量:用来存储数据的容器。不同的变量存储不同的数据。根据存储的数据类型的不同,变量的类型也不同。
-
创建变量 - 关键字:
var
- 语法:
var a
- 语法:
-
变量赋值
- 赋值运算符:
=
- 赋值运算符左边,为变量;赋值运算符右边为数据或其他变量
- 赋值运算符用于将右侧的数据或变量,存储在左侧的变量名中
- 语法:
a = "hello"
- 赋值运算符:
-
为了方便使用,声明变量还可以简写成如下形式:
- 声明时立即赋值:
var abc = 123;
- 声明多个变量并赋值:
var abc, qwe=10, asd=20, zxc;
- 声明时立即赋值:
-
变量名的命名规则
- 必须使用字母或下划线或$开头,变量中不允许出现特殊字符
如:_abc
,$123
,abc123
,msg
- 不允许使用关键字,保留字(见下方表格)
如:,var
,typeof
- 尽量语义化
如:age
,sex
,name
- 尽量使用数据类型的首字母做前缀
如:aChild
,oImg
,sTitle
- 组合单词,使用驼峰式
- 大驼峰:从第一个单词的首字母开始大写
如:CarFactory
,CreateTable
,AddEvent
- 小驼峰:从第二个单词的首字母开始大写
如:productDetailList
,bannerImgName
,menuTitle
- 大驼峰:从第一个单词的首字母开始大写
- 小技巧:使用个性化的前缀,避开敏感关键字和保留字
如:yslTypeof
,_var
,$this
- 必须使用字母或下划线或$开头,变量中不允许出现特殊字符
-
变量的原理:计算机程序运行在内存中,当使用关键字
var
声明一个变量时,计算机会从内存中划分一个空间,为存放不同类型的数据做准备。- 根据在内存中的存储形式分:
-
关键字和保留字
关键字:
break | do | instanceof | typeof | case | else |
new | var | catch | finally | return | void |
continue | for | switch | while | debugger* | function |
this | with | default | if | throw | delete |
in | try |
保留字(未来可能作为关键字存在):
abstract | enum | int | short | boolean | export |
interface | static | byte | extends | long | super |
char | final | native | synchronized | class | float |
package | throws | const | goto | private | transient |
debugger | implements | protected | volatile | double | import |
public | top | bottom | left | right |
小提示:凡是官方已经定义了功能的方法或函数(非关键字或保留字),如果你的本意不是为了覆盖或重写他们,也不要直接作为变量名,如:alert,console,sort,repeat
过于语义化的单词,也不推荐直接使用,如:button;
可以添加前缀后使用,如:myButton,backButton,_button等
七、运算符
JS中的常见运算符有:算术、赋值、关系、逻辑、自增自减等
-
算术运算符:
+
,-
,*
,/
,%
var a = 1, b = 2; console.log(a + b); // 3 console.log(a - b); // -1 console.log(a * b); // 2 console.log(a / b); // 0.5 console.log(a % b); // 1 // + 两边只要有一边是字符,运算过程就是字符串的拼接,结果必然是字符型数据 // - * / % 会将两边的数据,先隐式转成数值,再进行运算(能转则转,不能转得到NaN) var a = "1", b = "2"; console.log(a * b); // 2 console.log(a / b); // 0.5 console.log(a - b); // -1 console.log(a + b); // "12" *****
+
,在js中,有两层中功能:- 算数之间的加法;
- 字符串的连接;
如果js的执行遇到了+
号,执行过程中,会先检测加号两边的数据类型,如果发现字符型,那就是字符的拼接
在js中,有许多运算符和我们概念中的运算符都是不一样的。
比如:=
==
===
并且不同数据类型之间的运算得到的结果,可能不是我们意想中的结果
我们需要关注的,就是这些不一样的部分 -
关系运算符:
<
,<=
,>
,>=
,!=
,==
,!==
,===
var num1 = 108; var num2 = 36; console.log(num1 > num2); // true console.log(num1 >= num2); // true console.log(num1 < num2); // false console.log(num1 <= num2); // false var num1 = "108"; var num2 = 36; console.log(num1 > num2); // true console.log(num1 >= num2); // true console.log(num1 < num2); // false console.log(num1 <= num2); // false // 两边只要有一边是数值,另一边也会转成数值,再进行运算 var num1 = "108"; var num2 = "36"; console.log(num1 > num2); // false console.log(num1 >= num2); // false console.log(num1 < num2); // true console.log(num1 <= num2); // true var num1 = "a"; var num2 = "A"; console.log(num1 > num2); // true console.log(num1 >= num2); // true console.log(num1 < num2); // false console.log(num1 <= num2); // false // 两边都是字符,按照字符的比较规则:逐位按照ASCII码进行比较 // a~z:97~122 // A~Z:65~90 var num1 = "108"; var num2 = 108; console.log(num1 == num2); // true console.log(num1 != num2); // false // 两边只要有一边是数值,另一边也会转成数值,再进行运算 console.log(num1 === num2); // false console.log(num1 !== num2); // true // 没有数据类型转换,不仅比较数据,还比较类型
>
,>=
,<
,<=
,==
,!=
:两边只要有一边是数值,另一边也会转成数值,再进行运算===
,!==
:没有数据类型转换,不仅比较数据,还比较类型- 两边都是字符,字符的比较规则:逐位按照字符编码(ASCII)进行比较
- 运算结果为布尔值
-
逻辑运算符:
&&
,||
,!
// ||:或的两边只要有一个值为true,结果就是true; console.log(true || false); // true console.log(false || true); // true console.log(true || true); // true console.log(false || false); // false // &&:且的两边只要有一个值为false,结果就是false; console.log(true && false); // false console.log(false && true); // false console.log(true && true); // true console.log(false && false); // false // !:非,取反 console.log(!true); // false console.log(!false); // true
||
:或的两边只要有一个值为true
,结果就是true
;&&
:且的两边只要有一个值为false
,结果就是false
;!
:非,取反- 一般用来运算布尔,得到的结果一般也是布尔
-
赋值运算符:
=
,+=
,-=
,*=
,/=
,%=
var num1 = 10; num1 += 3; console.log(num1); // 13 var num2 = 10; num2 -= 3; console.log(num2); // 7 var num3 = 10; num3 *= 3; console.log(num3); // 30 var num4 = 10; num4 /= 3; console.log(num4); // 3.333333... var num5 = 10; num5 %= 3; console.log(num5); // 1
=
将=
号右侧的数据或变量,存储在左侧的变量中+=
,-=
,*=
,/=
,%=
规则:参考算术运算符
-
自增自减运算:
++
,--
++
:表示在变量原有的基础上增加1--
:表示在变量原有的基础上减小1
// 后自增或后自减:先使用原数据,再进行自增或自减计算 var a = 1; console.log(a++); // 1 console.log(a); // 2 var b = 1; console.log(b--); // 1 console.log(b); // 0 // 前自增或前自减:先进行自增或自减,再使用计算之后的数据 var a = 1; console.log(++a); // 2 console.log(a); // 2 var b = 1; console.log(--b); // 0 console.log(b); // 0
前自增与后自增有本质的区别,他们相同点都是为自身加了1,不同点是:
- 前自增:先计算(+1),在使用计算后的数值
- 后自增:先使用数值,再加计算(+1)
前自减和后自减同上
-
运算符的优先级:
算术
>比较
>逻辑
>赋值
// 已知一个年份2010,判断是否是闰年 // 闰年:1. 能被4整除,不能被100整除;2. 能直接被400整除 var year = 2012; var flag = year % 4 === 0 && year % 100 !==0 || year % 400 === 0; console.log(flag);
八、编程习惯
- 语句结束要加分号,虽然不加分号在JS语法上没有什么问题,但是建议不要省略分号,加了分号之后可以使用软件压缩。
- 这是一种良好的编程习惯(JavaScript权威指南)
九、练习题
- 熟练掌握以上所有知识点
- 为抵抗洪水,战士连续作战89小时,编程计算共多少天零多少小时?
- 小明要到美国旅游,可是那里的温度是以华氏度为单位记录的。
它需要一个程序将华氏温度(80度)转换为摄氏度,并以华氏度和摄氏度为单位分别显示该温度。
提示:摄氏度与华氏度的转换公式为:摄氏度 = 5/9.0*(华氏度-32) - var k=10;
var sum = k++ + ++k +k +k++;
console.log(k);
console.log(k); - 计算一个半径为80cm的圆的面积。打印到页面上。公式:π * r * r。假设:π = 3.1415
- 计算圆的周长,公式:2 * π * r
- 角度转弧度,公式:arc = π / 180 * deg
十、拓展
拓展1:关于浮点数:
电脑在运算过程中以正确的二进制浮点进行运算,但是我们输入的都是十进制的数,这两者并不是总是能转化的那么准确,有时候会得到正确的结果,但有时候就没那么幸运。
console.log(0.6+0.2); // 0.8
console.log(0.7+0.1); // 0.7999999999999999
拓展阅读:关于计算机中浮点数的精度计算问题
拓展2:NaN的概念和应用
NaN:是一种特殊的Number类型,表示非法的数值运算结果或意外转换的数字,NaN和任何数据都不相等。自身与自身也不相等。
console.log(NaN == NaN); // false
var a = 0;
var b;
var c = a + b;
console.log(c); // NaN
如何判断NaN
可以使用isNaN()函数,该函数判断括号内的值是否是NaN,是就返回true,不是就返回false
var a = 0;
var b;
var c = a + b;
console.log(c); // NaN
console.log(isNaN(c)); // true
// 注意:isNaN内会发生隐式类型转换
// 当数据能够被严格转成数值时,isNaN的结果为false,表示不是NaN(见下章:数据类型的转换)
console.log(isNaN( "hello" )); // true
console.log(isNaN( "123a" )); // true
console.log(isNaN( "123" )); // false