JavaScript 基础
JavaScript 特点
- 用于完成 html 网页交互
- 脚本语言
- 弱类型的
- 客户端的脚本
- 解释性的,边解释边执行
- 区分大小写
JavaScript 组成
ECMAScript、浏览器对象模型(BOM)、文档对象模型(DOM)
网页上引入 js 脚本三种形式
1. 网页内部使用
<script>
标签添加—-><body></body>
后面
<script> |
2. 引入外部 js 脚本
- 添加 JavaScript 文件,在里面编写代码
- 在 html 页面中添加标签,引入外部文件
<script type="text/javascript" src="要引入文件的相对路径" ></script>
3. 在网页标签元素的属性中添加
<input type="button" name="btn" value="请点击" onclick="alert('hello world!!!')"/>
三种引入 JavaScript 脚本的方式分别适合在什么时候用呢?
- 如果在标签属性中添加,只能作用于本标签,不能实现效果的重用
- 如果在页面内部通过 Script 标签引入,可以实现本页面的效果共享
- 引入外部 js 文件,可以实现页面间的代码共享,保证网页结构代码和效果代码相分离
标识符
变量名,函数名,属性以及函数中的参数都属于标识符
命名规则
- 只能包含数字,字母,下划线和$ ,但是不能以数字开头
- 不能包含其他符号
- 不能和 js 中关键字,保留字冲突
JavaScript 注释
- 单行 //
//注释内容
- 多行注释 /_ _/
/*注释内容*/
系统弹框
-
alert("");
警示框 -
confirm("");
确认框,包含确认,取消按钮
var n = confirm("-----?"); //得到的值是布尔类型的 |
- 可以让用户输入的提示框
var 变量名 = prompt("提示给用户的信息", "默认值"); |
- 用户点击确定,能够返回用户输入的值
- 用户点击取消,返回的值是 null
JavaScript 下载解析
- head: 先下载 js 脚本,再显示页面—-》当网络不好时,用户只能看到空白页面并且一直等待网页显示
- body: 先显示网页内容,然后遇到 js 脚本时再下载解析—》当网络不好时,用户可以先看到没有效果的页面
- body 后面 html2.0 不支持
为了优化加载速度大多使用异步加载(放在 body 后面),先加载页面后实现效果
变量与数据类型
- console.log(“”); 向控制台输出一句话(浏览器的控制台,f12 可以打开)多用于程序调试,观察变量的值
- javaScript 是弱类型的,松散型的
变量
- 声明
- var 关键字声明变量
- 变量声明
- var 变量名;
- 同时定义多个变量: var 变量名 1,变量名 2,….;
- 变量赋值:
- var 变量名=值;
- 同时定义多个变量赋值: var 变量名 1=值,变量名 2=值,….;
- 变量声明
- let 关键字定义变量
- let 定义的变量,只能在定义的代码块中使用
if (true) { |
- let不存在变量提升(var存在变量提升)---->必须声明赋值之后才能使用
console.log("name" + name); //不会报错 |
- let 定义的变量会有暂时性死区
let num1 = 10; |
- 不允许重复的声明变量(在相同作用域中)
let a = 1; |
- 赋值
JavaScript 语言是弱类型的 - 先声明再赋值
- 不用声明直接赋值 x=10;//ok
- 常量
使用 const 关键字
语法:const PI=3.14;
注意:
- 常量值是只读的,不能修改
- 和 let 的作用域是一样的
数据类型
undefined
表示:变量声明了,但是没有初始化
var x; //声明但是没有初始化 |
注意:变量未初始化和变量没有定义是不同的概念
null
表示空的值
跟 undefined 的区别是:undefined 变量定义了 但是跟本就没有赋值
如:var x; 此时x的值就是undefined |
String 字符串
语法:定义 时可以用“” 或者’ ‘,但是前后必须匹配
var str1 = "bbb"; |
注意:
- 字符串的值不能更改
- toString()方法,可以将 数值,对象,布尔,字符串 转换成字符串
可以使用 String()来进行判断一个变量的值是否为 null 或 undefined
var num=100; |
- String()函数
可以将任意类型转换成 String 字符串,包括 null 和 undefined
number
可以存储任何数字,整型和浮点型
var n1 = 100; |
注意:浮点数值的最高精度是 17 位小数,但在进行算数计算时其精确度远远不如整型。
特殊值和方法
- infinity :当大于或小于某个界限时,该值会被自动转换为特殊值——Infinity。
- isFinite()函数可以判断一个数值是否无穷大。
- 它会把参数转换为数值,如果得到的结果是 NaN、Infinity 或-Infinity,函数返回 false(假),其他情况返回 true(真)。
- NaN:非数值(Not a Number)
- 任何涉及 NaN 的操作(例如 NaN/5)都会返回 NaN。
- NaN 与任何值都不相等,包括 NaN 本身
- isNaN():检测一个值是否为 NaN
规则:- isNaN 方法会把参数转换为数值,若不能转换为数值则函数返回 false。
- 任何不能被转换为数值的值都会导致这个函数返回 true。
- parseInt() 解析字符串并返回一个整数或 NaN,可以解析二进制,八进制和十六进制的数值.
- parseFloat():解析字符串并返回一个浮点数
- parseFloat()函数始终都会忽略前导的零,且不具备传入基数的能力
Boolean
值: true false
转型函数 Boolean()
规则:
- String 类型:任何非空字符串转换为 true,空字符串(””)转换为 false;
- Number 类型:任何非零数值(包括无穷大)转换为 true,0 和 NaN 转换为 false;
Object 类型
任何对象转换为 true,null 转换为 false;
注意:当遇到流程控制语句(如 if 语句)也会对数据自动执行相应的 Boolean 转换
typeof
来判断一个值或变量究竟属于哪种数据类型。
typeof 操作符返回的数据类型有以下几种:
- undefined
- boolean
- string
- number
- object
- function
运算符
表达式:JavaScript 中短语,包括变量,字面量和运算符,简单表达式可以使用运算符组合成复杂表达式
一元运算符
只有一个操作数
如:a++ a-- ++b --b
注意:在 javascript 可以对任何值使用, 包括字符串,布尔值,浮点值和对象
var a = "89"; |
执行顺序
- ++i:先自增再运算
- i=i+1
- 其他
- i++;先运算再自增
- 其他运算
- i=i+1
算术运算符
- 加法
运算: - 求和
- 连接(跟字符串运算)
- 注意:NAN 和任何类型运算都是 NAN
var result1 = 1 + 2; //3 |
- 减法
求差时遇到字符串,布尔类型,NAN,null 等非数字类型时,先按规则转换成数字,再进行减法运算
var result1 = 5 - true; //4,因为true被转换成了1 |
- 乘法
求积时遇到字符串,布尔类型,NAN,null 等非数字类型时,先按规则转换成数字,再进行减法运算
var result1 = 100 * 70; //7000 |
- 除法
运算符由斜杠符号(/)表示,遇到非数字类型时先转换为数字再运算
var result1 = 100 / 50; // 2 |
- 取模(求余)
%–à 求余数
关系运算符
相等(==)、不相等(!=)、全等(===)和不全等(!==)
- == 和 === 的区别
- ==会进行类型转换
- ===不会转换类型
- 运算规则
- 如果操作数都是数值,则按照数值比较
- 如果两个操作数都是字符串,则比较两个字符对应的字符编码值
- 如果一个操作数是数值,则将另一个操作数转换为数值,然后进行数值比较
- 如果一个操作数是一个布尔值,则先将其转换为数值,然后再执行比较
逻辑运算符
- &&(并且)
两边不全是 boolean 类型 - 第一个表达式转换为 false,最终的结果为第一个操作数
- 第一个表达式转换为 true,最终的结果为第二个操作数
- || (或者)
两边不全是 boolean 类型
- 第一个表达式转换为 false,最终的结果为第二个操作数
- 第一个表达式转换为 true,最终的结果为第一个操作数
console.log(Boolean("1234")); //true 非空字符串 |
赋值运算符
右边赋值给左边+= -= *= /= %=
函数
定义调用
- 方式一
定义: |
- 方式二
定义: |
函数的参数
- 定义函数是传入的参数是形参
- 调用函数时传入的参数是实参
- 形参和实参没有必然联系,形参只是占位符,并且方便函数内使用
- javaScript 中,形参和实参的个数可以不一致,但是注意 java 中必须保持一致
- 获取参数的方式:argument 对象
- argument[0]:获得调用函数时传入的第一个实参
- argument[1]:获得调用函数时传入的第二个实参…以此类推
- argument.length 属性可以获得实参个数
例子:求最大值
function getMax() { |
函数返回值
function 函数名(形参) { |
变量作用域
- 全局作用域
- 局部作用域
如:在函数中定义的变量局部作用域 - 注意:如果在函数内部定义变量没有用 var 声明,直接赋值,那么将是一个全局变量
- 全局变量声明了之后,在程序的各个部分都可以使用,包括在函数里面
- 但是在函数内定义的局部变量,只能在函数内部使用
作用域链
在函数内部没有定义,就会在上一级作用域里面找
由内向外的作用域中寻找变量,直到找到为止
如果找到全局作用域也没找到,那么该变量的值为 undefined
闭包
可以读取一个函数内部变量函数
因为变量作用域的关系,导致内部可以读取全局变量,但是外部却不能访问内部变量
- 如何能从外部读取内部变量?
可以在函数内部再定义一个函数
function f1() { |
- 作用
- 读取到函数内部的变量
- 函数内部变量的作用范围扩大,常驻内存不会被回收
不用太纠结到底怎样才算闭包,其实我们每一个写的函数都是一个简单的闭包
立即执行函数
把函数的定义和调用合在一起
(function () { |
块级作用域与函数的声明
ES6 之前 函数不能声明在块级作用域里的,函数的声明是会全部提升至顶部
ES6 块级作用域里可以声明函数,但是函数声明的行为类似于 let,在块级外部是不能访问的
if(){ |
现如今:
- 允许在块级中声明函数】
- 函数的生命类似于 var,会有提升
- 函数的生命是会提升至头部
函数参数的默认值
在 ES6 之后,允许为参数指定默认值
function f1(x, y = 18) { |
- 不允许有同名参数
function f2(x, x, y = 18) { |
- 参数默认值是不能传值,每次都重新计算表达式默认的值,惰性求值
- 参数默认值的位置
- 一般来说,定义了默认值的参数,应该是尾参数,如果为非尾参数设置默认值,实际上并没有办法省略
- 如果不是尾参数,可以显示输入 undefined 但是 null 不行