JavaScript,本篇文章简称js。来自YouTobe上最热门的Javascript速成教程,硬性要求你有html和css的基础!十分推荐有其他编程语言基础的人阅读!(本人有Java、C++、Python的基础,轻松起飞,完了直接学Vue无压力,照着代码敲到底,你也可以的)
学习环境准备
工具和插件 我使用的工具是vscode,需要你建立好文件夹,像我这样的,里面有准备好的案例文件: 还需要你按照一个插件 Live Server 按照好后可以在html源代码页面右键,打开测试一下。 代码保存,浏览器页面也会随着更新:(代码我放在下面) 代码案例 index.html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>JS For Beginners</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>JS For Beginners</h1>
</header>
<section class="container">
<form id="my-form">
<h1>Add User</h1>
<div class="msg"></div>
<div>
<label for="name">Name:</label>
<input type="text" id="name">
</div>
<div>
<label for="email">Email:</label>
<input type="text" id="email">
</div>
<input class="btn" type="submit" value="Submit">
</form>
<ul id="users"></ul>
</section>
<script src="main.js"></script>
</body>
</html>
style.css代码:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
line-height: 1.6;
}
ul {
list-style: none;
}
ul li {
padding: 5px;
background: #f4f4f4;
margin: 5px 0;
}
header {
background: #f4f4f4;
padding: 1rem;
text-align: center;
}
.container {
margin: auto;
width: 500px;
overflow: auto;
padding: 3rem 2rem;
}
#my-form {
padding: 2rem;
background: #f4f4f4;
}
#my-form label {
display: block;
}
#my-form input[type='text'] {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border-radius: 5px;
border: 1px solid #ccc;
}
.btn {
display: block;
width: 100%;
padding: 10px 15px;
border: 0;
background: #333;
color: #fff;
border-radius: 5px;
margin: 5px 0;
}
.btn:hover {
background: #444;
}
.bg-dark {
background: #333;
color: #fff;
}
.error {
background: orangered;
color: #fff;
padding: 5px;
margin: 5px;
}
main.js准备用来练习的,并没有写代码。
Js脚本引入方式
首先介绍 js的两种引入方式
- 内置
<script> 标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS Study</title>
</head>
<body>
<h1>JS Study</h1>
<script>
alert('Hello,world!')
</script>
</body>
</html>
- 外链js文件
<script src="main.js"></script>
标签推荐放到body 底部,因为要先加载html这样的重要内容的页面
js测试
可以在浏览器中的console调试,点击F12,使用clear() 可以清空控制台 可以使用console对象调试,这回在控制台提示相应的内容
console.log('Hello,world')
console.error('This is an error!')
console.warn('This is a warning!')
可以到MDN查看文档,据说这是最好的js文档
变量var、let、const
var 是全局变量; let 、const 是局部变量。 let 可以修改引用; const 不可以被修改引用,是constant(常量)的缩写,相当于Java中final修饰的变量。
let score = 10
score = 20
const score = 10
score = 20
数据类型
js中有这6种数据类型: String、Number、Boolean、null、undefined、Symbol
const name = 'Forward'
const age = 22
const rating = 4.5
const flag = true
const x = null
const y = undefined
let z
console.log(typeof rating)
字符串的拼接
const name = 'Forward'
const age = 22
console.log('My name is'+ name +', and I am '+ age)
console.log(`My name is ${name},and I am ${age}`)
const s = `My name is ${name},and I am ${age}`
console.log(s)
字符串长度
const s = 'Hello, world'
console.log(s.length)
字符串所有字符变大写/小写
const s = 'Hello, world'
console.log(s.toUpperCase())
console.log(s.toLowerCase())
从字符串中截取部分字符串,通过索引,获取两索引之间的字符串
const s = 'Hello, world'
console.log(s.substring(0,5))
方法之间可以连接
const s = 'Hello, world'
console.log(s.substring(0,5).toUpperCase())
字符串分隔,存放到数组中并返回,根据参数(字符串)分隔,结果不包含用于分割的字符串
const s = 'Hello, world'
console.log(s.split(''))
const it = 'compute, technology, mouse, key, test'
console.log(it.split(', '))
Array 数组
结构方式创建数组
const numbers = new Array(0,1,2,3,4)
console.log(numbers)
javascript中的数组存放的数据类型可以不同的,相比很多编程语言更灵活
const fruits = ['apples','oranges','bear',10,false]
console.log(fruits)
数组的访问:通过索引方式
const fruits = ['apples','oranges','bear',10,false]
console.log(fruits[1])
数组元素的修改,也是通过索引方式
const fruits = ['apples','oranges','bear',10,false]
fruits[3] = 'banana'
console.log(fruits[3])
数组常用方法
const fruits = ['apples','oranges','bear',10,false]
fruits.pop()
fruits.push('mangos')
fruits.unshift('watermelon')
console.log(Array.isArray(fruits))
console.log(Array.isArray('hello'))
console.log(fruits.indexOf('mangos'))
console.log(fruits)
Object 对象
对象用 { } 表示,数组用 [ ] 表示 对象中的属性用 变量名:值 的方式表示,属性之间用","分隔
const person = {
firstName : 'Seen',
lastName : 'Forward',
age : 21,
hobbies : ['music','movies','sports'] ,
address : {
province:'辽宁',
city : '鞍山',
no : 206
}
}
console.log(person)
对象元素/属性的访问
console.log(person.firstName +' '+ person.lastName)
console.log(person.hobbies[1])
console.log(person.address.city)
解构
const {firstName,lastName,address:{city}} = person
console.log(firstName+' '+lastName)
console.log(city)
可以在对象中直接添加属性
person.email = 'forward.seen@foxmail.com'
console.log(person.email)
对象数组
const objArr = [
{
id:1001,
name:'Forward',
isStudent:true
},
{
id:1002,
name:'YiYi',
isStudent:true
},
{
id:1003,
name:'Gosling',
isStudent:false
}
]
console.log(objArr)
console.log(objArr[0].name)
JSON
在线转换JSON工具的网址:https://www.freeformatter.com/json-formatter.html
上面objArr转成JSON对象之后样式:
[
{
"id": 1001,
"name": "Forward",
"isStudent": true
},
{
"id": 1002,
"name": "YiYi",
"isStudent": true
},
{
"id": 1003,
"name": "Gosling",
"isStudent": false
}
]
通过比较可以发现,JSON的格式与javascript对象相似,只是它的属性名也是字符。
现在JSON的格式你已经知道了,那JSON是什么?有什么用呢?怎么用呢?
JSON: JavaScript Object Notation(JavaScript 对象标记法)。 JSON 是一种存储和交换数据的语法。 JSON 是通过 JavaScript 对象标记法书写的文本。
JSON用于交换数据 当数据在浏览器与服务器之间进行交换时,这些数据只能是文本。 JSON 属于文本,并且我们能够把任何 JavaScript 对象转换为 JSON,然后将 JSON 发送到服务器。 我们也能把从服务器接收到的任何 JSON 转换为 JavaScript 对象。 以这样的方式,我们能够把数据作为 JavaScript 对象来处理,无需复杂的解析和转译。
发送数据(从前端发送到服务器): 如果您的数据存储在 JavaScript 对象中,您可以把该对象转换为 JSON,然后将其发送到服务器。
const objArrJSON = JSON.stringify(objArr)
console.log(objArrJSON)
接收数据(从后台发送到前端): 如果您以 JSON 格式接收到数据,您能够将其转换为 JavaScript 对象:
const objArrJS = JSON.parse(objArrJSON)
console.log(objArrJS)
循环
For循环
for(let i = 0;i <= 10; i++){
console.log(i)
}
for(let i = 0; i<11 ; i++){
console.log(`For Loop Number: ${i}`)
}
While循环
let i = 0
while(i < 10){
console.log(`While Loop Number:${i}`)
i++
}
数组的遍历
有这样一个数组:
const objArr = [
{
id:1001,
name:'Forward',
isStudent:true
},
{
id:1002,
name:'YiYi',
isStudent:true
},
{
id:1003,
name:'Gosling',
isStudent:false
}
]
1.使用for循环
for(let i = 0; i < objArr.length; i++){
console.log(objArr[i].name)
}
2.使用增强for循环 上面并不是最好的方式,更推荐这种方式遍历数组对象:
for(let obj of objArr){
console.log(obj.id)
}
迭代数组foreach,map可以让我们从数组中创建新的数组,filter可以根据条件创建新数组:
3.forEach forEach() 中的参数是一个函数,函数中有个参数名字随意起,代表单个元素
objArr.forEach(function(obj){
console.log(obj.name)
})
4.map map是返回的是一个数组,它是把原数组中的对象处理后返回
const nameArr = objArr.map(function(obj){
return obj.name
})
nameArr.forEach(function(name){
console.log(name)
})
再来个高级点的处理,处理成一个新的对象
const ojb2Arr = objArr.map(function(obj){
let filterObj = {
id:obj.id+1000,
name:obj.name
}
return filterObj
})
ojb2Arr.forEach(function(obj){
console.log(obj)
})
5.filter filter是根据返回的条件过滤符号要求的对象并放到一个新的数组中
const obj3Arr = objArr.filter(function(obj){
return obj.isStudent === true
})
console.log(obj3Arr)
filter、map、filter可以连续使用
objArr.filter(function(obj){
return obj.isStudent === true
}).map(function(obj){
return obj.name
}).forEach(function(name){
console.log(name)
})
lambda表达式 lambda表达式使函数式编程变得更简单
objArr.filter(obj => obj.isStudent).forEach(obj => console.log(obj.name))
条件
if
== 只在乎值的本身,不关注值的类型,只要值相等(自动转成Number类型比较),就为true === 不仅比较值,还看类型是否相等,值相同但类型不相等仍为false
const x = 10
if(x == 10){
console.log('x is 10')
}
if(x == '10'){
console.log('x is 10')
}
if(x === '10'){
console.log('x is 10')
}
if-else
if(x === '10'){
console.log('x is 10')
}else{
console.log('x is not 10')
}
有时可能需要多层if-else
if(x < 10){
console.log('x is lower than 10')
}else if(x > 10){
console.log('x is more than 10')
}else{
console.log('x is equals 10')
}
逻辑运算符 &&、||、!
&& 是两个条件都为true时,整个表达式才能为true,否则为false
const y = 20
if(x > 10 && y === 20){
console.log('The condition is true')
}
|| 是两个条件中只要有一个为true,那么整个表达式就为true,都为false才为false
if(x > 10 || y === 20){
console.log('The condition is true')
}
! 是把boolean值取反,即!true = false ,!false = true
if(!(1<0)){
console.log('!1<0 = true')
}
当条件表达式中同时存在&&和||时,&&的优先级更高
if(x > 10 || y === 20 && y < 20){
console.log('The condition is true')
}
三元运算符 condition?code1:code2 如果条件为true,就执行code1的代码,为false执行code2的代码
const color = x > 10 ? 'red' : 'blue'
console.log(color)
三元运算符的效率要比if-else高一些
switch switch 是匹配case ,若为true 则的执行代码其后面的代码; break 关键字可以用于跳出循环以及switch 代码块
const x = 10
const color = x > 10 ? 'red' : 'blue'
switch(color){
case 'blue':
console.log('The color is blue')
break
case 'red':
console.log('The color is red')
break
default:
console.log('The color is not red or blue')
break
}
函数function
定义函数
function addNum(num1,num2){
return num1+num2
}
调用 函数定义后并不能自己执行,需要调用去执行代码
const sum = addNum(5,7);
console.log(sum)
还可以给参数列表中的参数初始化默认值,当调用的函数没有传递参数时,就使用这个默认值
function addNum2(num1=1,num2=2){
return num1+num2
}
console.log(addNum2())
console.log(addNum2(6,7))
lambda表达式 还可以使用lambda表达式使函数的写法更加精简
const addNum3 = (num1=1,num2) => {return num1+num2 }
console.log(addNum3(3,4))
还可以更加精简,return可以省略,函数体中只有一条语句时可以省略{}
const addNum4 = (num1,num2) => num1 + num2
console.log(addNum4(2,3))
当只有一个参数且没有默认值时,可以省略()
const addNum5 = num => num+5
console.log(addNum5(4))
还可以在foreach中使用lambda表达式
const arr = [1,2,3,4,5,6]
arr.forEach(e => console.log(e))
面向对象
两种实现方式:
1.构造函数Constructor function
function 函数名(参数列表,或者说是属性列表){} ,这里函数名首字母需要大写
function Person(firstName,LastName,dob){
this.firstName = firstName
this.LastName = LastName
this.dob = dob
}
使用构造函数创建对象: new 类名(实参列表)
const person1 = new Person('Forward','Seen','2-24-2022')
const person2 = new Person('YY','S','2-23-2022')
访问对象
console.log(person1)
访问对象属性
console.log(person1.firstName+' '+person1.LastName)
console.log(person2.dob)
对象的属性还可以是对象、函数(或者说方法)
function Person(firstName,LastName,dob){
this.firstName = firstName
this.LastName = LastName
this.dob = new Date(dob)
this.getBirthDay = function(){
return this.dob.getFullYear() +'/'+ this.dob.getMonth() +'/'+ this.dob.getDay()
}
this.getFullName = function(){
return `${this.firstName} ${this.LastName}`
}
}
const person = new Person('Forward','Seen','2-24-2022')
console.log(person.dob)
console.log(person.dob.getFullYear())
console.log(person.getBirthDay())
console.log(person.getFullName())
原型
Person.prototype.getBirthDay = function(){
return this.dob.getFullYear() +'/'+ this.dob.getMonth() +'/'+ this.dob.getDay()
}
Person.prototype.getFullName = function(){
return `${this.firstName} ${this.LastName}`
}
2.Class (ES6类,特别推荐有其他语言基础的人使用)
class Person{
constructor(firstName,LastName,dob){
this.firstName = firstName
this.LastName = LastName
this.dob = new Date(dob)
}
getBirthDay(){
return this.dob.getFullYear() +'/'+ this.dob.getMonth() +'/'+ this.dob.getDay()
}
getFullName(){
return `${this.firstName} ${this.LastName}`
}
}
创建对象的方式与之前的一样
const person1 = new Person('Forward','Seen','2-26-2022');
console.log(person1.getFullName())
DOM
之前的案例派上用场了: 你看到的样式图 DOM(Document Object Model,文档对象模型)
console.log(window)
window.alert('1')
因为window对象的优先级别很高,所以不用写window就可以直接使用window中方法 一切即window(这就类似Java中的Object对象,所有的类都有Object的方法,万物皆对象) window中有很多对象,比如:
localStorage是浏览器中的一种存储方式 innerHeight、innerWidth fetch是发起HTTP请求的方法 window中的document就是构成DOM(文档对象模型)中的文档
alert('1')
可以通过document从文档中选取元素
Single element 选取单个元素 你可以是使用document.getElementXXX 的方式
const myForm = document.getElementById("my-form")
console.log(myForm)
可以通过类名获取元素,返回的是html代码的数组
console.log(document.getElementsByClassName('item'))
该数组还可以通过索引访问
console.log(document.getElementsByClassName('item')[1])
还可以通过标签名访问
console.log(document.getElementsByTagName('li'))
我们还可以使用document.querySelector 来选取元素 更加推荐这种方式,因为只要往里放入对应选择器参数即可
console.log(document.querySelector('#my-form'))
console.log(document.querySelector('h1'))
如果是选取多个元素,就用document.querySelectorAll
console.log(document.querySelectorAll('.item'))
console.log(document.querySelectorAll('li'))
遍历
const items = document.querySelectorAll('.item')
items.forEach(item =>{
console.log(item)
})
操纵DOM的常用API 首先使用一个例子:
const ul = document.querySelector('.items')
console.log(ul)
ul.remove()
原样式: 移除标签后: 可以访问子元素,这里举例访问最后一个子元素,并移除,观察效果变化
ul.lastElementChild.remove()
可以修改元素中的内容,这里修改第一个子标签的内容
ul.firstElementChild.textContent = 'Hello'
还可以通过索引的方式访问子元素数组
ul.children[1].innerText = 'Forward'
还可以用innerHtml识别内容中的标签,也就是插入html代码
ul.lastElementChild.innerHTML = '<h4>Hello</h4>'
可以使用DOM修改样式 有一个按钮的例子:
const btn = document.querySelector('.btn')
btn.style.background = 'purple'
我们一般使用DOM操纵事件
给按钮添加一个事件监听器,第一个参数是事件,第二个是事件触发行为的函数
btn.addEventListener('click',event=>console.log('clicked'))
btn.addEventListener('click',e =>{
e.preventDefault()
console.log('clicked')
})
查看事件对象
btn.addEventListener('click',e =>{
e.preventDefault()
console.log(e)
})
event.target 可以获取到事件的对象或者说目标
btn.addEventListener('click',e =>{
e.preventDefault()
console.log(e.target)
})
再来写一个高级点、复杂点的
btn.addEventListener('click',e=>{
e.preventDefault()
document.querySelector('#my-form').style.background = '#ccc'
document.querySelector('.items').classList.add('bg-dark')
document.querySelector('.items').lastElementChild.innerHTML = '<h2>HELLO</h2>'
})
常用事件
事件名称 | 事件行为 |
---|
click | 鼠标单击事件(当单击该标签时,触发事件行为) | mouseover | 鼠标移入事件(当鼠标移动到元素中,触发事件行为) | mouseout | 鼠标移出事件 |
综合案例
案例说明 点击submit按钮,如name或email没有输入,则提示Please input… 3秒后这个提示会自动消失 当用户输入后,会将name和email显示在下面,并且可以继续输入添加。
JS代码实现
const myForm = document. querySelector( '#my-form' ) ;
const nameInput = document.querySelector( '#name' ) ;
const emailInput = document.querySelector( '#email' );
const msg = document.querySelector('.msg' );
const userList = document.querySelector('#users');
myForm.addEventListener('submit',e => {
e.preventDefault()
if(nameInput.value === '' || emailInput.value ===''){
msg.classList.add('error')
msg.innerHTML = 'Please input your name and email!'
setTimeout(()=>msg.remove(),3000)
}else{
const li = document.createElement('li')
li.appendChild(document.createTextNode(`${nameInput.value}${emailInput.value}`))
userList.append(li)
nameInput.value = ''
emailInput.value = ''
}
})
|