定义与特性
- 弱类型语言,变量类型可变化
- 特点
- 交互性,信息交互
- 安全性,不允许直接访问本地硬盘
- 跨平台性,有浏览器的地方就能只用它
JavaScript的引入方式
- 外部式
<head> <script type="text/javascript" src="......"></script> </head>
- 内部式
<head> <script> code... </script> </head>
注释
多行注释
/* 注释内容 */
单行注释
// 注释内容
变量
可以存放值的内存
变量类型
数值类型:number
字符串类型:string
对象类型:object
布尔类型:boolean
函数类型:function
数组类型:array
特殊值
undefined:未定义,所有JS变量在未赋值状态下的默认值
null:空值
NaN:Not a number 非数值,但是NaN自己却是一个数,是number类型
如何定义变量
使用关键字 var
let
const
写作方式:var 变量名 = 值;
或 var 变量名;
<script>
var jsNotValue; // 未赋值状态
var jsHaveValue = 123; // 赋值状态
</script>
作用域
全局作用域:全局(在函数之外)声明的变量拥有全局作用域。全局变量可以在 JavaScript 程序中的任何位置访问。
函数作用域:局部(函数内)声明的变量拥有函数作用域。局部变量只能在它们被声明的函数内访问。
块作用域:在块 { } 内声明的变量
循环作用域:在循环体内的区域,例如for循环
var let const
-
const
- 常量,必须在声明的语句中同时指定值,且不可在改变
<script> // 正确写法 const PI = 3.14159265359; // 错误写法 const PI; PI = 3.14159265359 </script>
- 常量是块级范围的,非常类似用 let 语句定义的变量。
- 在块作用域中,let可以重新声明const定义的变量,但是作用域仅限于此块作用域,而因为在块作用域中var声明会被提升为全局变量,则会抛出异常
- const可以是任何类型值,包括对象也可以是数组
- 可以更改对象或数组中的属性的值也可以添加属性和值,但是不可以重新为常量赋值,因为const定义的常量是数组的引用而不是数组的本身
<script> // 您可以创建 const 对象: const car = {type:"porsche", model:"911", color:"Black"}; // 您可以更改属性: car.color = "White"; // 您可以添加属性: car.owner = "Bill"; // 不可以重新赋值 car = {type:"Volvo", model:"XC60", color:"White"}; </script>
- 可以更改数组中的内同但是不可以重新给常量赋值
<script> // 您可以创建常量数组: const cars = ["Audi", "BMW", "porsche"]; // 您可以更改元素: cars[0] = "Honda"; // 您可以添加元素: cars.push("Volvo"); // 不可以重新赋值 cars = ["Honda", "Toyota", "Volvo"]; </script>
- 同一作用域或块中,不允许将已有的 var 或 let 变量重新声明或重新赋值给 const
-
全局作用域
- 全局声明的变量,在任何地方都能使用
-
函数作用域
- 函数内部声明的变量,只能在函数内部使用
-
块作用域
-
var即使在 块 { } 作用域内声明,其他部位依旧可以使用
let可以声明拥有块作用域的变量,只能在块作用域内使用
<script> { var x = 10; } // 此处可以使用 x { let x = 10; } // 此处不可以使用 x </script>
-
var在块作用域中重新声明外部变量,会覆盖块外变量,let不会重新声明块外变量
<script> var x = 10; // 此处 x 为 10 { var x = 6; // 此处 x 为 6 } // 此处 x 为 6 var x = 10; // 此处 x 为 10 { let x = 6; // 此处 x 为 6 } // 此处 x 为 10 </script>
-
-
循环作用域
- 在for循环中重新声明外部变量,var会覆盖,let不会
<script> var i = 7; for (var i = 0; i < 10; i++) { // 循环体 } // 此处,i 为 10 let i = 7; for (let i = 0; i < 10; i++) { // 循环体 } // 此处 i 为 7 </script>
-
重新声明
- var允许在任何位置重新声明
- 在相同的作用域中,不允许let重新声明一个var变量,同样var也不可以重新声明let变量
- 在相同的作用域中,不允许let重新声明,不同作用域是可以的
关系运算
一般运算
>=
:大于等于
>
:大于
<=
:小于等于
<
:小于
==
:等于,不在乎数据类型的值的比较
===
:全等于,值和数据类型都要一样
!=
:不等于,不在乎类型
!==
:值不等于或类型不等
%
:取余
++
:递加
--
:递减
JS中所有的变量都能作为boolean类型使用
0 | null | undefined | “”(空字符串,无空格) 均被认定为false
逻辑运算
&&
且运算
当多个表达式全为true,则返回最后一个表达式的值
当多个表达式有一个为false,返回第一个为false的表达式的值
||
或运算
当多个表达式全为false,返回最后一个表达式的值
当多个表达式有一个为true,返回第一个为true的表达式的值
&&
和 ||
运算,均会产生短路原则,即当表达式执行后,一旦有结果则不会继续执行后面的表达式,不在乎后面表达式的结果,因为总的来说已经有结果了
!
取反运算
数组
如何定义数组
<script>
var arrayName1 = []; // 定义空数组
var arrayName2 = [1,'2',false]; // 有值的数组
</script>
JS中只要通过数组下标进行赋值,那么数组会以最大的下标值进行扩容
<script>
var arrayName1 = []; // 定义空数组
arrayName1[16] = 'str';
/* 直接赋值数组中index为16的,则本来是空数组
的,会被扩容,从index=0 到 index=16,并且下标16之前的数组内的值都是
undefined */
</script>
数组的遍历
for
循环 或者 forEach
<script>
var arrayName2 = [1,'2',false];
// for循环
for(i = 0; i < arrayName2.length; i++) {
console.log(arrayName2[i])
}
// forEach
arrayName2.forEach(element => {
console.log(element)//数组内的值
});
// forEach
arrayName2.forEach(function(item,index){
console.log(item+' '+index);//数组内的值和下标
});
</script>
除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。
数组常用方法
toString()
:把数组转换为数组值(逗号分隔)的字符串
join()
:将所有数组元素结合为一个字符串可以指定分隔符
pop()
:从数组中删除最后一个元素,并返回被删除的值
push()
:向数组添加一个新的元素,返回新数组的长度
shift()
:删除首个数组元素,并重新分配索引,返回被删除的值
unshift()
:向数组头添加新元素,返回新数组的长度
length
:数组长度
splice(index ,del-count,value1,value2···)
:向数组添加新项
index 指定被添加位置的索引
del-count 指定要删除数组中元素的个数
value是添加的值、
concat()
:合并两个数组,会更改现有数组。它总是返回一个新数组,可以使用任意数量的数组参数。
slice(start-index , end-index)
:从数组中截取并返回新数组,不会影响原有数组,end-index可省略
sort()
:以字母顺序对数组进行排序,若比较数字可以配合使用比值函数
<script>
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a}); //降序
</script>
reverse()
:反转数组中的元素
函数
使用关键字 function
定义
定义函数
// 方式一 function 函数名称(形参) { 函数体 } // 方式二 var 函数名称 = function(形参){ 函数体 }
JS中函数不可以重载(可以理解为同一个函数名称的函数通过不同的形参个数就是不同的函数,这在Java中可以,但是在JS中不可以),若产生重载,这后来定义的函数将会覆盖之前的函数
因为JS函数中有个隐藏形参 arguments
,这个参数不需要被定义,但是却可以获得全部传入函数内部的实参,类似一个参数集合,即使函数形参定义的是一个,但是调用函数时候传入了多个实参, arguments
都能接受到,使用方式可以参考数组
自定义对象
// 方式一,用new var 变量名 = new Object(); 变量名.属性名 = 值; 变量名.函数名 = function(形参){ 函数体 }; // 方式二,用 {} var 变量名 = { 属性名 : 值, 属性名 : 值, 函数名 : function(形参){ 函数体 }, 属性名 : 值 };
<script>
// 方式一
var objName = new Object();
objName.width = 500;
objName.func = function(){
console.log("I am best");
}
var w = objName.width;// 访问属性
// 方式二
var objName2 = {
width:500,
func:function(){
console.log("I am best");
},
height:300
}
var w = objName2.width;// 访问属性
</script>
方式二中,赋值用冒号,并且每个属性赋值之间用逗号相隔,最后一个不用写逗号
访问对象中的属性 变量名.属性名
变量名.函数名
JavaScript事件
事件
什么是事件?事件是电脑输入设备与页面进行交互的响应,我们称之为事件
常用事件
onload
:加载完成事件,页面加载完成后运行,通常用于JS代码初始化
onclick
:单击事件
onblur
:失去焦点事件,常用于输入框失去焦点后验证输入内容
onchange
:内容发生改变事件,常用语下拉列表和输入框内内容发生改变时
onsubmit
:表单提交事件,常用语表单提交前验证表单中所有项目是否正确
事件的注册(绑定)
- 静态注册事件:通过html 标签的事件属性直接赋于事件响应后的代码,这种方式我们叫静态注册
- 动态注册事件:是指先通过js 代码得到标签的dom 对象,然后再通过dom 对象.事件名= function(){} 这种形式赋于事件响应后的代码,叫动态注册
onload
事件
静态
<head>
<script type="text/javascript">
// onload 事件的方法
function onloadFun() {
alert('静态注册onload 事件,所有代码');
}
</script>
</head>
<!--静态注册onload 事件,onload 事件是浏览器解析完页面之后就会自动触发的事件,body标签的属性,通过这个属性注册-->
<body οnlοad="onloadFun();">
</body>
动态
<head>
<script type="text/javascript">
// onload 事件动态注册。是固定写法
window.onload = function () {
alert("动态注册的onload 事件");
}
</script>
</head>
<body>
</body>
onclick
事件
静态
<head>
<script type="text/javascript">
function onclickFun() {
alert("静态注册onclick 事件");
}
</script>
</head>
<body>
<!--静态注册onClick 事件,通过button的onclick属性-->
<button onclick="onclickFun();">按钮1</button>
</body>
动态
<head>
<script type="text/javascript">
window.onload = function () {
//getElementById 通过id 属性获取标签对象
var btnObj = document.getElementById("btn01");
// 2 通过标签对象.事件名= function(){}
btnObj.onclick = function () {
alert("动态注册的onclick 事件");
}
}
</script>
</head>
<body>
<button id="btn01">按钮2</button>
</body>
输出
innerHTML
:定义HTML内容,也可用于获取
<body>
<h1>我的第一张网页</h1>
<p>我的第一个段落</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = 5 + 6;
</script>
</body>
alert
:警告框显示数据
<head>
<script>
function haha(){
alert("click")
}
</script>
</head>
<body>
<button onclick="haha()"></button>
</body>
console.log
: 控制台显示数据
<head>
<script>
function haha(){
console.log("click")
}
</script>
</head>
<body>
<button onclick="haha()"></button>
</body>
DOM模型
Document Object Model 文档对象模型
HTML中的标签、属性、样式、文本等都是用DOM管理
document
文档对象,代表整个网页
获取HTML对象
getElementById
:返回对拥有指定 id 的第一个对象的引用
常用于JS指定标签获取之后进行操作,所以id属性一定要在HTML中保持唯一性
getElementByName
:返回带有指定名称的对象集合
返回的是拥有相同name的集合
getElementByTagName
:返回带有指定标签名的对象集合,作为 NodeList 对象,即有顺序的集合,是标签元素在HTML页面中从上到下的顺序
NodeList 对象代表一个有顺序的节点列表,使用方法参考数组
getElementsByClassName
:返回文档中所有指定类名的元素集合,作为 NodeList 对象,多个类名使用空格分隔,如 “test demo”
创建HTML对象
createElement
:创建标签节点
createTextNode
:创建文本节点
<script>
function myFunction(){
var btn=document.createElement("BUTTON");
var t=document.createTextNode("CLICK ME");
btn.appendChild(t);
document.body.appendChild(btn);
};
</script>
节点常用方法及属性
标签文本等都可以称作节点
appendChild(Node)
:添加一个子节点
childNodes
:返回所有子节点,空白也会识别为节点
firstChild
:返回第一个子节点
parentNode
:返回父节点
previousSibling
:返回前一个兄弟节点
innerHTML
:返回指定标签下所有内容
innerText
:返回指定标签下所有文本
DOM事件监听
addEventListener(event, function, useCapture)
:事件监听
useCapture是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的
在 HTML DOM 中有两种事件传播的方法:冒泡和捕获。
事件传播是一种定义当发生事件时元素次序的方法。假如
<div>
元素内有一个<p>
,然后用户点击了这个<p>
元素,应该首先处理哪个元素“click”事件?在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的:首先处理
<p>
元素的点击事件,然后是<div>
元素的点击事件。在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的:首先处理
<div>
元素的点击事件,然后是<p>
元素的点击事件。默认值是 false,将使用冒泡传播,如果该值设置为 true,则事件使用捕获传播。
允许向相同元素添加多个事件,同时不覆盖已有事件
document.getElementById("myBtn").addEventListener("click", displayDate);
removeEventListener(event, function)
:删除事件监听器
传递参数
使用匿名函数
element.addEventListener("click", function(){ myFunction(p1, p2); });
正则表达式
定义正则
- var patt = new RegExp("…");
- var patt = /…/;
- 推荐 -
验证正则
test
方法
patt.test(检验值)
符合返回true,否则返回false
常用正则规则
e
:是否包含e[abc]
:是否包含a或b或c[a-z]
:是否包含小写字母[A-Z]
:是否包含大写字母[0-9]
:是否包含数字
元字符
\w
:是否包含字母(a-z A-Z),数字,下划线\W
:是否包含除了上方那些意外的字符\d
:是否包含数字\s
:是否包含空白字符
量词
n+
:字符串中包含至少一个n字符n*
:字符串中包含零个或多个n字符n?
:字符串中包含零个或一个n字符n{x}
:字符串中包含x个连续的n字符n{x,y}
:字符串中包含至少x至多y个连续的n字符n{x,}
:字符串中包含至少x个连续n字符n$
:以n字符结尾^n
:以n字符开始
量词具有最小满足且中断检测的性质
当满足最小条件时,检测就会中断,不会继续检测
例如(4,5,6)中当满足x个连续的n字符后检测就不会,即使x+1…个在字面上是不满足条件的,但是因为从前到后的检测先检测到符合x个连续的n字符,就会中断检测,不会再检测x+1个
一般情况下不会单独使用,需要配合(7、8)
当 ^
和 $
一起使用的时候,代表完全匹配
/^\w{5,12}$/
即完全匹配5-12位的字母、数字、下划线
字符串常用方法
length
:字符串长度
indexOf(str,index)
:返回指定字符串在文本中首次出现的索引,没有则返回-1,index可选,是指定从索引多少之后开始查询,不支持正则表达式
lastIndexOf(str,index)
:返回指定字符串在文本中最后一次出现的索引,没有则返回-1,index可选,是指定从索引多少之后开始查询
search(str)
:返回指定字符串在文本中首次出现的索引,没有则返回-1
slice(start-index,end-index)
:提取字符串的某个部分,并返回提取部分内容,end-index省略则返回start-index后所有剩余部分,若为负值则从字符串末尾开始向前查询
substring(start-index,end-index)
:同slice()
,但不支持负值
substr(index,length)
:返回提取部分的文字,index指定起始索引位置,length指定提起长度,若省略length则返回剩余所有,负值index则从字符串末尾开始查询
replace(queryStr, replaceStr)
:替换文本,不会改变原有文本,返回替换后的新文本,只替换首个匹配,对大小写敏感,支持正则表达式
如需替换所有匹配,请使用正则表达式的 g 标志(用于全局搜索)
<script> str = "Please visit Microsoft and Microsoft!"; var n = str.replace(/Microsoft/g, "company"); </script>
toUpperCase()
:把字符串转换为大写
toLowerCase()
:把字符串转换为小写
trim()
:删除字符串两端的空白符
如需支持 IE 8,您可搭配正则表达式使用 replace() 方法代替
<script> var str = " Hello World! "; alert(str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')); </script>
charAt(index)
:返回字符串中指定下标的字符
split()
:将字符串转换为数组
<script> var txt = "a,b,c,d,e"; // 字符串 txt.split(","); // 用逗号分隔 txt.split(" "); // 用空格分隔 txt.split("|"); // 用竖线分隔 var txt = "Hello"; // 字符串 txt.split(""); // 分隔为字符 </script>
match(regexp)
:方法根据正则表达式在字符串中搜索匹配项,并将匹配项作为 Array 对象返回
<script> var text = "The rain in SPAIN stays mainly in the plain"; text.match(/ain/g) // 返回数组 [ain,ain,ain] </script>
includes(str)
:是否包含指定字符串,包含返回true
模板字面量
增强版字符串,使用 `
反引号
基本用法
<script> let message = `Hello world!`; console.log(message); // "Hello world!" </script>
以上代码中,使用模板字面量语法创建一个字符串,并赋值给message变量,这时变量的值与一个普通的字符串无异
<script> let message = `\`Hello\` world!`; console.log(message); // "`Hello` world!" console.log(typeof message); // "string" console.log(message.length); // 14 </script>
如果想在字符串中包含反引号,只需使用反斜杠( \ )转义即可
多行字符串
<script> let message = `Multiline string`; // "Multiline // string" console.log(message); console.log(message.length); // 16 //\n 来指示换行的插入位置 let message = `Multiline\nstring`; </script>
只需在想要的位置直接换行即可,此处的换行会同步出现在结果中,在反引号之内的所有空白符都是字符串的一部分,因此需要特别留意缩进,也可以在模板字面量中使用 \n 来指示换行的插入位置
变量占位符
变量占位符允许将任何有效的JS表达式嵌入到模板字面量中,并将其结果输出为字符串的一部分
变量占位符由起始的 ${ 与结束的 } 来界定,之间允许放入任意的 JS 表达式。
<script> let name = "Nicholas", message = `Hello, ${name}.`; console.log(message); // "Hello, Nicholas." </script>
<script> let count = 10, price = 0.25, message = `${count} items cost $${(count * price).toFixed(2)}.`; console.log(message); // "10 items cost $2.50." </script>
<script> function fn() { return "Hello World"; } `foo ${fn()} bar` // foo Hello World bar </script>
模板字面量本身也是 JS 表达式,因此可以将模板字面量嵌入到另一个模板字面量内部
<script> let name = "Nicholas", message = `Hello, ${ `my name is ${ name }` }.`; console.log(message); // "Hello, my name is Nicholas." </script>
异常
try { 供测试的代码块 } catch(err) { 处理错误的代码块 }
可以自定义抛出的异常err,使用throw
<script>
try {
if(x == "") throw "空的";
if(isNaN(x)) throw "不是数字";
x = Number(x);
if(x < 5) throw "太小";
if(x > 10) throw "太大";
}
catch(err) {
message.innerHTML = "输入是 " + err;
}
</script>
finally 表示无论结果如何都会被执行
<script>
try {
if(x == "") throw "是空的";
if(isNaN(x)) throw "不是数字";
x = Number(x);
if(x > 10) throw "太大";
if(x < 5) throw "太小";
}
catch(err) {
message.innerHTML = "错误:" + err + ".";
}
finally {
document.getElementById("demo").value = "";
}
</script>
this
- 在方法中,this 指的是所有者对象。
- 单独的情况下,this 指的是全局对象。
- 在函数中,this 指的是全局对象。
- 在函数中,严格模式下,this 是 undefined。
- 在事件中,this 指的是接收事件的元素。
- 像 call() 和 apply() 这样的方法可以将 this 引用到任何对象
类
使用关键字 class
定义类
必须使用 constructor()
构造函数
类不是对象
class ClassName { constructor() { ... } method_1() { ... } method_2() { ... } . . . }
<script>
class Car {
constructor(name, year) {
this.name = name;
this.year = year;
}
age() {
let date = new Date();
return date.getFullYear() - this.year;
}
}
let myCar1 = new Car("Ford", 2014);
let myCar2 = new Car("Audi", 2019);
document.getElementById("demo").innerHTML = "My car is " + myCar1.age(year) + " years old.";
</script>
继承
使用 extends
关键字
在类中使用 super()
方法引用父类
<script>
class Car {
constructor(brand) {
this.carname = brand;
}
present() {
return 'I have a ' + this.carname;
}
}
class Model extends Car {
constructor(brand, mod) {
super(brand);//引用父类并且初始化父类(传参)
this.model = mod;
}
show() {
return this.present() + ', it is a ' + this.model;
}
}
let myCar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = myCar.show();
</script>
get和set方法
<script>
class Car {
constructor(brand) {
this._carname = brand;
}
get carname() {//get方法
return this._carname;
}
set carname(x) {//set方法
this._carname = x;
}
}
let myCar = new Car("Ford");
//set方法赋值
myCar.carname = "Volvo";
//get方法取值,虽然get是方法,凡是也要用取变量的方式
document.getElementById("demo").innerHTML = myCar.carname;
</script>
静态方法
<script>
class Car {
constructor(name) {
this.name = name;
}
static hello(x) {
return "Hello " + x.name;
}
}
let myCar = new Car("Ford");
//静态调用,直接用类名
document.getElementById("demo").innerHTML = Car.hello(myCar);
</script>
使用 state
定义
JSON
- 数据是名称/值对
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
{ "company":"big" "employees":[ { "firstName":"Bill", "lastName":"Gates" }, { "firstName":"Steve", "lastName":"Jobs" }, { "firstName":"Alan", "lastName":"Turing" } ] }
将JSON字符串转为对象
JSON.parse(text)
AJAX
AJAX是技术不是编程语言,异步更新网页,不需要重新加载网页全部
<script>
function loadDoc() {
// Ajax 的核心是 XMLHttpRequest 对象
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt",true);
xhttp.send();
}
</script>
- XMLHttpRequest 对象方法
- abort() 取消当前请求
- getAllResponseHeaders() 返回头部信息
- getResponseHeader() 返回特定的头部信息
- open(method, url, async, user, psw)
- method:请求类型 GET 或 POST
- url:文件位置
- async:true(异步)或 false(同步)
- user:可选的用户名称
- psw:可选的密码
- send() 将请求发送到服务器,用于 GET 请求
- send(string) 将请求发送到服务器,用于 POST 请求
- setRequestHeader() setRequestHeader()
- XMLHttpRequest 对象属性
- onreadystatechange 定义当 readyState 属性发生变化时被调用的函数
- readyState
- 0:请求未初始化
- 1:服务器连接已建立
- 2:请求已收到
- 3:正在处理请求
- 4:请求已完成且响应已就绪
- status
- 200: “OK”
- 403: “Forbidden”
- 404: “Not Found”
- responseText 以字符串返回响应数据
注意事项
- 避免使用全局变量
- 在函数中使用的变量应该使用关键字被声明为局部变量
- 避免未定义值,初始化记得赋值
- 避免是用new的方式声明变量而产生Obj
- 请使用 {} 来代替 new Object()
- 请使用 “” 来代替 new String()
- 请使用 0 来代替 new Number()
- 请使用 false 来代替 new Boolean()
- 请使用 [] 来代替 new Array()
- 请使用 /()/ 来代替 new RegExp()
- 请使用 function (){}来代替 new Function()
- 为函数的参数设置默认值
- 使用default结束switch