JavaScript(作者:Brendan Eich):是一种具有函数优先的轻量级,解释型,弱类型或即时编译型的高级编程语言,且是世界上最流行的脚本语言,其源代码不需经过编译,而是由浏览器解释运行,用于控制网页的行为。
特性:
(1)脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。
(2)基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
(3)简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。
(4)动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等操作JavaScript都可直接对这些事件给出相应的响应。
(5)跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提上机器上的浏览器支 持JavaScript脚本语言,JavaScript已被大多数的浏览器所支持。
1、内部标签
<script>
//......
</script>
2、外部引用
alter.js
alert('Hello JavaScript!');
test.html
<script src="alter.js">script>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script>
// 1.定义变量 变量类型 变量名 = 变量值
var num = 1;
// 2.条件控制
if (2>1){
// alert("true")
}
script>
head>
<body>
body>
html>
数值,文本,图形,音频,视频…
变量
var 王者 = "荣耀";
数值
js不区分小数和整数,Number
NaN // not a number
Infinity // 表示无限大
字符串
‘abc’ “abc”
布尔值
true,false
逻辑运算
&& 两个都为真,结果为真
|| 一个为真,结果为真
! 真即假,假即真
比较运算符
=
== 等于(类型不一样,值一样,也会判断为true)
=== 绝对等于(类型一样,值一样,结果为true)
这是一个js的缺陷,坚持不要使用’=='比较
须知:
浮点数问题:
console.log((1/3) === (1-2/3))// false
尽量避免使用浮点数进行运算,存在精度问题!
console.log(Math.abs(1/3-(1-2/3)))// true
null和undefined
数组
Java的数组必须是相同类型的对象~,js中不需要这样!
// 保证代码的可读性,尽量使用[]
var arr = [1,3,25,'hello',null,true];
new Array(1,3,25,'hello',null);
取数组下标,如果越界了,就会undefined。
对象
对象是大括号,数组是中括号。
每个属性之间使用逗号隔开,最后一个不需要添加。
// Person person = new Person(1,2,3);
var person = {
name: 'Desiy',
age: 21,
sex: '男'
}
取对象的值
person.name
> "Desiy"
peison.age
> 21
<script>
// 前提:IDEA需要设置支持ES6语法
'use strict';// 严格检查模式,预防JavaScript的随意性导致产生的一些问题。
let i = 1;// 局部变量建议使用let定义
</script>
1、正常字符串我们使用单引号,或者双引号包裹。
2、注意转义字符 \
\'
\n
\t
\u4e2d \u#### Unicode字符
"\x41" Ascll字符
3、多行字符串编写
<script>
'use strict';
// tab键上的 `
var msg =
`
hello
world
nihao
你好`
</script>
4、模板字符串
<script>
'use strict';
// tab键上的 `
let name = "Desiy";
let age = 21;
let msg = `你好呀,${
name}`
</script>
5、字符串长度
str.length
6、字符串的可变性,不可变
7、大小写转换
// 注意是方法,不是属性。
str.toUpperCase()
str.toLowerCase()
8、student.indexOf(’’)
9、substring
[)
student.substring(1)// 从第一个字符串截取到最后一个字符串
student.sbustring(1,3)// [1,3)
Array可以包含任意的数据类型
var arr = [1,2,3];// 通过下标取值和赋值
1、长度
arr.length
==注意:==假如给arr.length赋值,数组大小就会发生变化。但是如果赋值过小,元素就会丢失。
2、indexOf
,通过元素获得下标索引
arr.indexOf()
字符串的"1"和数字1是不同的
3、slice()截取Array的一部分,返回一个新的数组,类似于String中的substring。
4、push()
,pop()
尾部
push:压入到尾部
pop:弹出尾部的一个元素
5、unshift()
,shift()
头部
unshift:压入到头部
shift:弹出头部的一个元素
6、排序sort()
["B","C","A"]
arr.sort()
["A","B","C"]
7、元素反转reverse()
["B","C","A"]
arr.reverse()
["A","C","B"]
8、concat()
["B","C","A"]
arr.concat([1,2,3])
["B","C","A", 1, 2, 3]
arr
["B","C","A"]
==注意:==concat()并没有修改数组,只是会返回一个新的数组。
9、连接符join
打印拼接数组,使用特殊的字符串连接
["B","C","A"]
arr.join()
"C-B-A"
10、多维数组
arr = [[1,2],[3,4],["5","6"]]
arr[1][1]
4
arr[1][0]
3
数组:存储数据(如何存,如何取,方法都可以自己实现!)
若干个键值对
var 对象名 = {
属性名: 属性值,
属性名: 属性值,
属性名: 属性值
}
js中对象,{…}表示一个对象,键值对描述属性xxxx:xxxx,多个属性之间使用逗号==,==隔开,最后一个不需要加逗号!
JavaScript中的所有的键都是字符串,值是任意对象!
1、对象赋值
person.name = "Desiy"
"Desiy"
person.name
"Desiy"
2、使用一个不存在的对象属性,不会报错!undefined
3、动态的删除属性,通过delete删除对象的属性
delete person.name
true
person
4、动态的添加,直接给新的属性添加值即可
peison.haha = "haha"
"haha"
person
5、判断属性值是否在这个对象中,xxx in xxx
'age' in person
true
// 继承
'toString' in person
true
6、判断一个属性是否是这个对象自身拥有的hasOwnProperty()
person.hasOwnProperty('toString')
false
person.hasOwnProperty('age')
true
if判断
while循环,避免程序死循环。
while(age<10){
age = age+1;
console.log(age)
}
do{
age = age+1;
console.log(age)
}while(age<10)
for循环
for(let i = 0;i < 100;i ++){
console.log(i)
}
forEach循环(5.1引入)
let arr = [5, 136, 6, 651, 556, 226]
//函数
arr.forEach(function (value) {
console.log(value)
})
for…in
// for(let index in object){}
for (let num in arr){
console.log(arr[num])
}
Map:
'use strict'
let map = new Map([['Tome',2],['Jack',3],['Desiy',21]]);
let name = map.get('Desiy');// 通过key获得value
map.set('admin',321);
console.log(name)
==Set:==无序不重复的集合
let set = new Set([3,1,1,1,]);// set可以去重
set.add(2);// 添加
set.delete(1);// 删除
console.log(set.has(3));// 判断是否包含某个元素
遍历数组
//通过for of,for in 下标
var arr = [1,2,3]
for (var x of arr){
console.log(x)
}
遍历Map
var map = new Map([['Tome',2],['Jack',3],['Desiy',21]]);
for (var x of map){
console.log(x)
}
遍历Set
var set = new Set([1,2,3]);
for (var x of set) {
console.log(s)
}
定义方式一
绝对值函数
function abs(x){
if(x >= 0){
return x;
}else{
return -x;
}
}
一旦执行到return代表函数结束,返回结果。
定义方式二
var abs = function(x){
if(x >= 0){
return x;
}else{
return -x;
}
}
function(x){…}是一个匿名函数,但是可以把结果赋值给abs,通过abs就可以调用函数。
调用函数
abs(10)// 10
abs(-10)// 10
参数问题:JavaScript可以传任意参数,也可以不传参数。
参数进来是否存在的问题?
假设不存在参数,如何规避?
let abs = function (x) {
//手动抛出异常来判断
if (typeof x !== 'number'){
throw 'Not a Number';
}
if (x > 0){
return x;
}else {
return -x;
}
}
arguments是一个JS免费赠送的关键字。
代表传递进来的所有参数,是一个数组。
let abs = function (x) {
console.log("x->"+x);
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
if (x > 0){
return x;
}else {
return -x;
}
}
问题:arguments包含所有的参数,我们有时候想多使用多余的参数来进行附加操作。需要排除已有参数。
rest
Before:
if (arguments.length>2){
for (let i = 2;i
ES6引入的新特性,获取出了已经定义的参数之外的所有参数。
function many(a,b,...rest) {
console.log("a->"+a);
console.log("b->"+b);
console.log(rest);
}
rest参数只能写在最后面,必须用…标识。
变量的作用域
在JavaScript中,var定义变量实际是有作用域的。也就是如果在函数体中声明,则在函数体外不可以使用该变量。在’use strict’模式下“x = x+2;”会直接报红。
function f() {
var x = 1;
x = x+1;
}
x = x+2;// Uncaught ReferenceError: x is not defined
如果两个函数使用了相同的变量名,只要在函数内部,就不冲突。
function f() {
var x = 1;
x = x+1;
}
function f2() {
var x = 1;
x = x+1;
}
内部函数可以访问外部函数的成员,反之则不行。
function f() {
var x = 1;
function f2() {
var y = x+1;
}
var z = y+1;// Uncaught ReferenceError: y is not defined
}
假设,内部函数变量和外部函数的表量重名。
function f(){
var x = 1;
function f2(){
var x = 'A';
console.log('in'+x);// inA
}
console.log('out'+x);// out1
f2()
}
f()
提升变量的作用域
function f(){
var x = "x"+y;
console.log(x);
var y = 'y';
}
结果:xundefined
说明:JS执行引擎,自动提升了y的声明,但是不会提升变量y的赋值。所以养成规范:所有的变量定义都放在函数的头部。
全局变量
var x = 1;
function f(){
console.log(x);
}
f();
console.log(x);
全局对象window
var x = "x";
alter(x);
alter(window.x);// 默认所有的全局变量,都会自动绑定在window对象下。
alter()这个函数本身也是一个window变量:
var x = "x";
window.alter(X);
var old_alter = window.alter;
// old_alter(X);
window.alter = function(){
};
// alter()失效了
window.alter(111);
// 恢复alter
window.alter = old_alter;
window.alter(222);
JavaScript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错RefrenceError。
规范
由于我们所有的全局变量都会绑定到我们的window上,如果不同的JS文件,使用了相同的全局变量,就会冲突。解决:
// 自定义全局变量
var diy = {
};
diy.name = 'Desiy';
diy.add = function(a,b){
return a+b;
}
ES6 let关键字,解决局部作用域的冲突问题。
function f(){
// 如果这里是var,最后结果就会出现101;
for(let i = 0;i<100;i++){
console.log(i);
}
console.log(i+1);// Uncaught ReferenceError: i is not defined
}
常量const
在ES6之前,怎么定义常量:全部使用大写字母命名的变量就是常量。缺点:可以任意改变其值。
var PI = '3.14';
console.log(PI);// 3.14
PI = '3';
console.log(PI)// 3
now:
const PI = '3.14';
console.log(PI);// 3.14
PI = '3';// 爆红
定义-把函数放在对象里面,对象只有两个东西:属性和方法。
let Desiy = {
birth: 1998,
// 方法
age: function () {
let year = new Date().getFullYear();
return year=this.birth;
}
}
// 属性
Desiy.birth
// 方法,要带()
==this.==代表什么?拆开上面的代码:
function getAge(){
let year = new Date().getFullYear();
return year=this.birth;
}
let Desiy = {
birth:1998,
age: getAge
}
// Desiy.age() ->22
//getAge() ->NaN 直接调用getAge()实际上是window调用,它没有birth这个属性。
this是无法指向的,是默认指向调用它的那个对象;但是在JS中可以控制this指向;使用关键字apply。
function getAge(){
let year = new Date().getFullYear();
return year=this.birth;
}
let Desiy = {
birth:1998,
age: getAge
}
// Desiy.age() ->22
getAge.apply(Desiy,[])// this指向了Desiy,参数为空。
JavaScript、Java、C#等等都有面向对象的特点,但是JavaScript有一些区别。
类:模板
对象:具体的实例
在JavaScript中需要转换思维方式。
原型
let User = {
name: "Desiy",
age: 21,
sex: "男",
run: function () {
console.log(this.name + " is running...")
}
};
let Admin = {
name: "Tom"
};
//Admin的原型是User
Admin.__proto__ = User;// Admin可以执行run()函数了。
class继承
// ES6之前
function f1(name) {
this.name = name;
}
// 给f1新增一个方法
f1.prototype.sayHi = function () {
alert("Hi!")
};
class关键字,实在ES6引入的。
// ES6之后,定义一个类
class f1{
constructor(name) {
this.name = name;
}
sayHi(){
alert("Hi!")
}
}
class f2 extends f1{
constructor(name,age) {
super(name);
this.age = age;
}
info(){
alert("我的年龄:"+this.age);
}
}
let student = new f2("Desiy",21);
标准对象
typeof 123
"number"
typeof "123"
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof {
}
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"
基本使用
let now = new Date();
now.getFullYear();// 年
now.getMonth();// 月 0-11
now.getDate();// 日
now.getDay();// 星期几
now.getHours();// 时
now.getMinutes();// 分
now.getSeconds();// 秒
now.getTime();// 时间戳 全世界统一 1970 1.1 0:00:00 毫秒数
转化
now = new Date(1592466459734)
Thu Jun 18 2020 15:47:39 GMT+0800 (中国标准时间)
now.toLocaleString// 这里调用的是一个方法,不是一个属性。
ƒ toLocaleString() {
[native code] }
now.toLocaleString()
"2020/6/18 下午3:47:39"
now.toGMTString()
"Thu, 18 Jun 2020 07:47:39 GMT"
在JavaScript中一切皆为对象、任何js支持的类型都可以用JSON来表示。
格式:
JSON字符串和JS对象的转换
let json = JSON.stringify(user);
let obj = JSON.parse('{"name":"Desiy","age":21,"sex":"男"}');
BOM:浏览器对象模型
三方
window代表 浏览器窗口
window.innerHeight
382
window.outerWidth
1536
window.outerHeight
824
window.innerWidth
1536
// 可以调整浏览器窗口试试...
Navigator,封装浏览器信息
navigator.appVersion
"5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
navigator.userAgent
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
navigator.platform
"Win32"
大多数时候,我们不会使用navigator对象,因为会被人为修改!所以不建议使用这些属性来判断和编写代码。
screen
代表屏幕尺寸
screen.width
1536
screen.height
864
location代表当前页面的URL信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PSF2TeuI-1593049909740)(C:\Users\86923\AppData\Roaming\Typora\typora-user-images\image-20200619160154116.png)]
location.assign('')// 设置新的地址
document
代表当前页面,HTML DOM文档树
document.title
"Title"
document.title = "Hello World"
"Hello World"
获取具体的文档树节点
<script>
let element = document.getElementById('doc');
</script>
</head>
<body>
<dl id="doc">
<dt>Java</dt>
<dd>JavaSE</dd>
<dd>JavaEE</dd>
</dl>
</body>
获取cookie
document.cookie
服务器端可以设置cookie:httpOnly
history
history.back()// 后退
history.forward()// 前进
DOM:文档对象模型
核心:浏览器网页就是一个DOM树型结构。
获取DOM节点
// 对应的css选择器
let h1 = document.getElementById('h1');
let p1 = document.getElementById('p1');
let p2 = document.getElementById('p2');
let father = document.getElementById('father');
let children = father.children;// 获取父节点下的所有节点
更新节点
<div id="id1">
div>
<script>
let id1 = document.getElementById('id1');
script>
操作文本
操作CSS
id1.style.color = 'yellow';
id1.style.fontSize = '20px';
id1.style.padding = '1em'
删除节点
步骤:
<div id="father">
<h1>标题h1>
<p id="p1">p1p>
<p id="p2">p2p>
div>
<script>
let self = document.getElementById('p1');
let father = self.parentElement;
father.removeChild(self)
//这里的删除是一个动态的过程!
father.removeChild(father.children[0])
father.removeChild(father.children[1])
father.removeChild(father.children[2])
script>
注意:删除多个节点的时候,children是变化的。
插入节点
我们获得了某个DOM节点,如果这个DOM节点是空的,我们可以通过innerHTML添加一个元素,但是如果这个节点已经存在元素了,重复上面的操作会覆盖原来的元素。
追加
<p id="js">JavaScriptp>
<div id="list">
<p id="se">JavaSEp>
<p id="ee">JavaEEp>
<p id="me">JavaMEp>
div>
<script>
let js = document.getElementById('js');
let list = document.getElementById('list');
list.appendChild(js)// 追加到最后
script>
创建一个新的标签,实现插入
<script>
let js = document.getElementById('js');
let list = document.getElementById('list');
// 通过js创建一个新的节点
let newP = document.createElement('p');// 创建一个p标签
newP.id = 'newP';
newP.innerText = 'Hello';
list.append(newP);
// 创建一个标签节点(通过这个属性,可以设置任意的值)
let myScript = document.createElement('script');
myScript.setAttribute('type','text/javascript');
list.append(myScript);
// 创建一个style标签
let myStyle = document.createElement('style');
myStyle.setAttribute('type','text/css');
// 设置标签内容
myStyle.innerHTML = 'body{background-color: blue;}';
document.getElementsByTagName('head')[0].appendChild(myStyle);
</script>
insertBefore
let ee = document.getElementById('ee');
let js = document.getElementById('js');
let list = document.getElementById('list');
// 要包含的节点,insertBefore(newNode,targetNode)
list.insertBefore(js,ee);
表单是什么? form DOM树
表单的目的:提交信息
获得要提交的信息
<form action="post">
<p>
<span>用户名:span><input type="text" id="username">
p>
<p>
<span>性别:span>
<input type="radio" name="sex" value="man" id="boy">男
<input type="radio" name="sex" value="woman" id="girl">女
p>
form>
<script>
let username = document.getElementById('username');
let boy = document.getElementById('boy');
let girl = document.getElementById('girl');
// 得到输入框的内容
username.value;
// 修改输入框的内容
username.value = '111';
// 对于单选框,多选框等等固定的值,boy.value只能取到当前的值
boy.checked;// 查看返回的结果,是否为true,如果为true,则被选中。
girl.checked = true;// 赋值
script>
提交表单 MD5加密,表单优化。
<form action="#" method="post" onsubmit="return f()">
<p>
<span>用户名:span><input type="text" id="username" name="username">
p>
<p>
<span>密码:span><input type="password" id="input-password">
p>
<input type="hidden" id="md5-password" name="password">input>
<button type="submit">提交button>
form>
<script>
function f() {
let username = document.getElementById('username');
let password = document.getElementById('input-password');
let md5password = document.getElementById('md5-password');
md5password.value = md5(password.value);
// 可以检验判断表单内容,true就是通过提交,false就是阻止提交。
return true;
}
script>
在线测试JavaScript代码