文章目录
- [JS 入门](#JS 入门)
- [一、JS 概述](#一、JS 概述)
-
- [1、JS 特点](#1、JS 特点)
- [2、JS 组成](#2、JS 组成)
- [3、JS 初体验](#3、JS 初体验)
- 4、HTML引入JS
- [二、JS 基础语法](#二、JS 基础语法)
- [三、JS 函数](#三、JS 函数)
- [四、JS 作用域](#四、JS 作用域)
- [五、JS 事件](#五、JS 事件)
- 附录:ES6新特性
-
- [00、什么是 ES](#00、什么是 ES)
- [00、ES 的历史版本](#00、ES 的历史版本)
- 01、变量声明
- 02、模板字符串
- 03、函数的参数默认值
- 04、箭头函数
- 05、对象初始化简写
- 06、解构
- 07、延展操作符
- 08、map函数
- 09、reduce函数
JS 入门
一、JS 概述
1、JS 特点
- JS 不需要编译,浏览器可以直接解释运行。
- JS 是弱类型语言,变量声明不需要指明类型。(Java是强类型)
2、JS 组成
组成部分 | 作用 |
---|---|
ES(ECMA Script) | 构成了JS核心的语法基础 |
BOM(Browser Object Model) | 浏览器对象模型,用来操作浏览器上的对象 |
DOM(Document Object Model) | 文档对象模型,用来操作网页中的元素(标签) |
3、JS 初体验
html : 搭建网页结构
css : 美化网页
js : 实现交互效果
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JavaScript 初体验</title>
<style>
div {
color: red;
}
</style>
</head>
<body>
<div>内容1</div>
<div>内容2</div>
<!-- 点击按钮,调用指定的script函数 -->
<input type="button" value="按钮" onclick="checkAge()">
<script>
function checkAge() {
var result = confirm("你满18岁了吗?");
if (result) {
location.href = "http://www.baidu.com"
}
}
</script>
</body>
</html>
4、HTML引入JS
可以直接在 HTML 文件中使用 <script>
标签来嵌入 JavaScript 代码。这通常放在 <head>
或 <body>
部分。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Embed JS Example</title>
<script>
// 这里是 JavaScript 代码
function greet() {
alert("Hello, World!");
}
</script>
</head>
<body>
<h1>JavaScript 引入示例</h1>
<button onclick="greet()">点击我</button>
</body>
</html>
也可以通过 <script>
标签的 src
属性引入外部的js文件,这样可以使代码更加模块化和可维护。
javascript
// script.js
function greet() {
alert("Hello, World!");
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>External JS Example</title>
<script src="script.js" defer></script>
</head>
<body>
<h1>JavaScript 引入示例</h1>
<button onclick="greet()">点击我</button>
</body>
</html>
二、JS 基础语法
1、变量声明
es6
之前,统一用 var
声明。
javascript
var i = 1;
var j = 1.1;
var k = "abc";
es6
开始,用 let
声明变量(可以修改),用 const
声明常量(不能修改)。
javascript
// 变量
let a = 1;
a = 6.66;
console.log(a);
// 常量
const m = "abc";
m = 'bcd';
console.log(m);
2、基本数据类型
javascript
// 1. number 数字(包括整数和小数)
console.log(typeof 1)
console.log(typeof 1.1)
// 2. string 字符串(单引号 和 双引号都可以)
console.log(typeof 'haha')
console.log(typeof "xixi")
// 3. boolean 布尔
console.log(typeof true)
console.log(typeof false)
// 4. undefined 声明了未赋值
let n;
console.log(typeof n)
3、引用数据类型
1)数组
javascript
// 数组的声明(下标从0开始)
let arr = [1, 2, 3, 4, 5];
let arr = new Array(1, 2, 3, 4, 5);
let arr = Array.of(1, 2, 3, 4, 5);
let arr = Array.from("hello");
javascript
let arr = Array.from("hello");
console.log(typeof arr); // object
console.log(arr[1]); // e
console.log(arr); // ['h', 'e', 'l', 'l', 'o']
2)对象
javascript
let obj = {
name : 'zs',
age : 18,
married : false
};
console.log(typeof obj); // object
console.log(obj.name); // zs
console.log(obj); // {name: 'zs', age: 18, married: false}
3)函数
javascript
let f = function (a) {
console.log("函数");
}
console.log(typeof f); // function
4)null
javascript
// null 的类型也是 object
let n = null;
console.log(typeof n) // object
4、运算符
javascript
// 算数运算符
+ - * / % ++ --
// 赋值运算符
= += -= *= /= %=
// 比较运算符
> < == != === 恒等于 !== 不恒等于
// 逻辑运算符
&& || !
// 三目运算符
条件表达式 ?为真的逻辑 : 为假的逻辑
恒等于 ===
javascript
let d = "100"
let e = 100
console.log(d == e) // true == 仅比较字面值
console.log(d === e) // false === 不仅比较字面值,还比较类型
js
中,number + 非string类型 = number
- true=1、false=0、null=0、undefined=NaN(not a number)
javascript
let a = 100
let b = true // 1
let c = false // 0
let d = null // 0
let e
console.log(a + b); // 101
console.log(a + c); // 100
console.log(a + d); // 100
console.log(a + e); // NaN
5、条件判断
javascript
// if 语句
if (条件表达式) {
代码块;
} else if (条件表达式) {
代码块;
} else {
代码块;
}
// switch 语句
switch (条件表达式) {
case 满足条件1 :
代码块
break;
case 满足条件2 :
代码块
break;
default:
默认代码块;
}
任何类型都可以放在条件表达式
number
:0为false,非0为truestring
:空串为false,非空串为trueundefined
:false引用数据类型
:null为false,非null为true
javascript
let c = null
if (c) {
console.log(true);
} else {
console.log(false);
}
6、循环语句
javascript
// 1. 普通for循环
for (let i = 0; i < 10; i++) {
需要执行的代码;
}
// 2. 增强for循环 (e6支持)
for (let element of array) {
需要执行的代码;
}
// 3. 索引for循环
for (let index in array) {
let element = array[index]
需要执行的代码;
}
// 4. while循环
while (条件表达式) {
需要执行的代码;
}
// 5. do..while循环
do {
需要执行的代码;
} while (条件表达式);
// 6. break:跳出整个循环
// 7. continue:跳出本次循环,继续下次循环
三、JS 函数
js
函数用于执行特定功能的代码块,也可以称为js
方法
0、JS 函数特点
返回值:
- 用 return 返回,没有返回值可以省略 return
参数:
- 参数列表的变量不用写类型。
- 调用函数时,传入参数的个数不受函数限制(可以少也可以多,依次赋值,没有赋值到的是undefined)。
- JS函数内有一个隐藏变量 arguments(数组),它的元素是传入此函数的所有参数(可以直接调用 arguments)。
1、普通函数
使用 function
关键字定义的函数,可以在任何地方调用。
javascript
function 函数名(参数列表) {
函数体;
return 返回值; // 没有返回值可以省略....
}
代码示例:
javascript
function method() {
console.log("无参无返回")
}
method()
javascript
function method(a, b) {
return a + b;
}
// js的函数调用,传入参数个数不受函数限制(依次赋值,没有赋值是undefined)
let result1 = method(1)
let result2 = method(1, 2, 3)
console.log(result1); // 1 + undefined = NaN
console.log(result2); // 1 + 2 = 3
javascript
function method(a, b) {
let sum = 0;
// 隐藏变量arguments (数组), 它的元素是传入此函数的所有参数
for(let i = 0; i< arguments.length; i++){
sum += arguments[i]
}
return sum;
}
let result = method(1, 2, 3, 4, 5);
console.log(result); // 1+2+3+4+5=15
2、匿名函数
没有名称的函数,通常用于 回调 或 立即执行函数。
javascript
function (参数列表) {
函数体;
return 返回值; // 没有返回值可以省略....
}
代码示例:
javascript
// 匿名函数赋值给变量使用
let method = function (a) {
console.log("匿名函数" + a);
}
method("呵")
console.log(typeof method); // function
3、箭头函数
ES6提供了箭头函数(函数的简略写法,类似于Java中的Lambda表达式)
- 不需要
function
关键字来创建函数 - 省略
return
关键字 - 继承当前上下文的 this 关键字
javascript
// es5
function (resp, msg) {...}
// es6
(resp, msg) => {...}
// es6(如果函数只有一行,可以省略大括号和return)
(resp, msg) => ...
代码示例:
javascript
// es5
var add = function (a, b) {
return a + b;
}
console.log(add(100, 200))
// es6
let add = (a,b) => {
return a + b;
}
console.log(add(100, 200))
// es6 更简化写法
let add = (a, b) => a + b;
console.log(add(100, 200))
4、高阶函数
接受函数作为参数或返回一个函数的函数。
javascript
function higherOrderFunction(callback) {
callback();
}
higherOrderFunction(() => {
console.log("这是一个高阶函数");
});
5、异步函数
使用 async
关键字定义的函数,允许在函数内部使用 await
关键字来处理 Promise
。
javascript
async function asyncFunction() {
const result = await Promise.resolve("这是一个异步函数");
console.log(result);
}
6、对象方法
对象中的函数称为方法,可以通过对象调用。
javascript
let obj = {
name : "zs",
eat : function () {
console.log(this.name + "在吃饭");
}
}
obj.eat()
四、JS 作用域
1、全局作用域
在所有函数之外声明的变量具有全局作用域,可以在任何地方被访问。
javascript
var globalVar = "I am global";
function testGlobal() {
console.log(globalVar); // 可以访问全局变量
}
testGlobal(); // 输出: I am global
2、局部作用域
局部作用域是指在函数内部声明的变量,只能在该函数内部访问。这些变量在函数外部不可见。
javascript
function testLocal() {
var localVar = "I am local";
console.log(localVar); // 可以访问局部变量
}
testLocal(); // 输出: I am local
console.log(localVar); // 报错: localVar is not defined
3、块级作用域
let
和 const
声明的变量存在块级作用域(函数/代码块内部),而 var
声明的变量在外部也能访问(变量泄露)
javascript
{
var a = 'xyz'
}
console.log(a)
{
const m = 'a'
}
console.log(m)
{
let n = 'bcd'
}
console.log(n)
4、嵌套作用域
函数可以在其他函数内部定义,从而形成嵌套作用域。在这种情况下,内部函数可以访问其外部函数的变量。
javascript
function outerFunction() {
var outerVar = "I am from outer function";
function innerFunction() {
console.log(outerVar); // 可以访问外部函数的变量
}
innerFunction(); // 输出: I am from outer function
}
outerFunction();
5、作用域链
每个作用域都有一个指向其父作用域的指针,这称为作用域链。当在一个作用域中查找变量时,JavaScript 会沿着作用域链向上查找,直到找到变量或到达全局作用域为止。
javascript
var name = "John";
function outer() {
var name = "Jane";
function inner() {
console.log(name); // 输出: Jane,访问最近的作用域
}
inner();
}
outer();
6、闭包
闭包是指一个函数可以访问其外部作用域中的变量,即使外部函数已经执行完毕。闭包允许数据的封装和私有化。
闭包一定有 return 和 内存泄漏 吗?不一定,例如下列代码:
javascript
function outerFunction() {
let count = 0;
function innerFunction() {
console.log(outerVar); // 可以访问外部函数的变量
}
innerFunction(); // 输出: I am from outer function
}
outerFunction();
外部如果想要使用闭包的变量,则此时需要 return
javascript
function makeCounter() {
let count = 0; // `count` 变量是私有的
return function() {
count++; // 每次调用增加计数
return count;
};
}
const counter = makeCounter();
console.log(counter()); // 输出: 1
console.log(counter()); // 输出: 2
let c = counter(); // 2
闭包允许数据的封装和私有化。外部可以拿到count,但是无法修改count
如果不使用闭包,如下所示,则不能保证count
变量私有
javascript
let count = 0;
const counter = function() {
count++; // 每次调用增加计数
return count;
};
console.log(counter()); // 输出: 1
console.log(counter()); // 输出: 2
let c = counter(); // 2
c = 1000;
console.log(counter()); // 输出: 1001
五、JS 事件
js
是事件驱动型语言,可以监听用户的行为,并调用函数来完成用户交互功能
1、常用事件
markdown
1. 点击事件:
1. onclick 单击事件
2. ondblclick 双击事件 (double: 时间间隔很短两次单击)
2. 焦点事件
1. onblur 元素失去焦点
2. onfocus 元素获得焦点。
3. 加载事件:
1. onload 当前页面加载完成后触发。
4. 鼠标事件:
1. onmousedown 鼠标按钮被按下。
2. onmouseup 鼠标按键被松开。
3. onmousemove 鼠标被移动。
4. onmouseover 鼠标移到某元素之上。
5. onmouseout 鼠标从某元素移开。
5. 键盘事件:
1. onkeydown 某个键盘按键被按下。
2. onkeyup 某个键盘按键被松开。
3. onkeypress 某个键盘按键被按下并松开。
6. 改变事件
1. onchange 域的内容被改变(如下拉框)。
7. 表单事件:
1. onsubmit 提交按钮被点击。
2、事件绑定
将 事件 与 html 标签进行绑定,实现交互功能。可以通过 命名函数 和 匿名函数 进行注册
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>事件绑定</title>
</head>
<body>
<!--
普通函数
1. 给标签添加一个事件属性 这里是 onclick = "函数调用"
2. 定义事件绑定的函数
-->
<input type="button" value="普通函数" onclick="heihei('x')">
<script>
function heihei(a) {
alert("嘿嘿")
}
</script>
<!--
匿名函数
1. 先用找到标签对象
2. 标签对象.事件 = 匿名函数
-->
<input type="button" value="匿名函数" id="myid">
<script>
let btn = document.getElementById("myid");
btn.onclick = function () {
alert("嘻嘻")
}
</script>
</body>
</html>
附录:ES6新特性
参考文章:http://es6.ruanyifeng.com/
00、什么是 ES
ES(ECMAScript)是由 ECMA(一个类似W3C的标准组织)参与进行标准化的语法规范。
ES 定义了:
JavaScript 是 ES 的实现和扩展。ES 涵盖了各种 JS 的使用场景,无论是 浏览器环境 还是类似 node.js 的非浏览器环境。
ES 标准不定义 HTML 或 CSS 的相关功能,也不定义类似 DOM 的 Web API,这些都在独立的标准中进行定义。
00、ES 的历史版本
ECMAScript 标准的历史版本分别是1、2、3、5。
为什么没有第4版?其实,在过去确实曾计划发布提出巨量新特性的第4版,但最终却因想法太过激进而惨遭废除(这一版标准中曾经有一个极其复杂的支持泛型和类型推断的内建静态类型系统)。
ES4饱受争议,当标准委员会最终停止开发ES4时,其成员同意发布一个相对谦和的ES5版本,随后继续制定一些更具实质性的新特性。这一明确的协商协议最终命名为"Harmony",因此,ES5规范中包含这样两句话
ECMAScript是一门充满活力的语言,并在不断进化中。
未来版本的规范中将持续进行重要的技术改进
2009年发布的改进版本ES5,引入了 Object.create()、Object.defineProperty()、getters 和 setters、严格模式 以及 JSON 对象。
ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,2015年6月正式发布。
它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
01、变量声明
ES6 以前,用 var
声明变量;ES6之后,用 const
声明常量,用 let
声明变量
javascript
// es5 用 var
var i = 1;
var j = 1.1;
var k = "abc";
// es6 用 const 声明常量,用 let 声明变量
const m = "abc";
let a = 1;
let b = 3.1;
let c = 'abc'
注意:let
声明的是变量,可以修改;const
声明的是常量,不能修改
javascript
let a = 1;
a = 6.66;
console.log(a);
const m = "abc";
m = 'bcd';
console.log(m);
let
、const
声明的变量存在块级作用域(函数/代码块内部),而 var
声明的变量在外部也能访问(变量泄露)
javascript
{
var a = 'xyz'
}
console.log(a)
{
const m = 'a'
}
console.log(m)
{
let n = 'bcd'
}
console.log(n)
02、模板字符串
ES6支持将表达式嵌入字符串中进行拼接。用${}
来界定。
js
let username='Rose'
// es5
// 需要拼接变量
console.log('姓名是:' + username)
// es6
// 使用反引号,可以直接打印变量的值,表达式类似于java的el表达式
console.log(`姓名是:${username}`)
03、函数的参数默认值
ES6为参数提供了默认值。在定义函数时便初始化了这个参数,以便在参数没有被传递进去时使用。
js
function show(username='Jack') {
console.log(username);
}
// 传参后,使用传入的值
show('Rose');
// 没有传参,自动使用默认值 'Jack',而不是 undifined
show()
这样可以避免不传参时出现undefined
04、箭头函数
ES6提供了箭头函数(函数的简略写法,类似于Java中的Lambda表达式)
- 不需要function关键字来创建函数
- 省略return关键字
- 继承当前上下文的 this 关键字
js
// es5
function (response, message) {
......
}
// es6
(response, message) => {
.......
}
// es6(如果函数只有一行,可以省略大括号和return)
(response, message) => .......
javascript
// es5
var add = function (a, b) {
return a+b;
}
console.log(add(100,200))
// es6
var add = (a,b) => {
return a+b;
}
console.log(add(100, 200))
// es6 更简化写法
var add = (a, b) => a+b;
console.log(add(100, 200))
05、对象初始化简写
ES6之前,都是以键值对的形式书写对象。例如:
js
// es5
function people (username, age) {
return {
username: username,
age: age
}
}
console.log(people('Rose', 18));
ES6之后,以上代码可以简写为:
js
// es6
function people (username, age) {
// 对象的key 和 参数名 一致,可以简写如下
return {
username,
age
}
}
console.log(people('Jack', 88));
06、解构
数组 和 对象,是JS中最常用也是最重要的表示形式。
ES6之前,我们获取 数组 和 对象 中的元素:
javascript
// 对象
const people = {username:'Rose', age:18}
var username = people.username
var age = people.age
console.log(username + "," + age)
// 数组
const color = ['red', 'blue']
var color1 = color[0];
var color2 = color[0];
console.log(color1 + "," + color2)
ES6新增了解构
,这是将一个数据结构分解为更小的部分的过程
javascript
// 对象
const people = {username:'Rose', age:18}
const { username, age } = people;
console.log(username + "," + age)
// 数组
const color = ['red', 'blue']
const [color1, color2] = color
console.log(color1 + "," + color2)
07、延展操作符
ES6 新增了延展操作符,语法上是三个点,可以用来扩展对象或者数组。
接下来就展示一下它的用途。
javascript
// 原来的对象
const peopleOld = {username:'Rose', age:18}
// 重新生成一个对象,并基于之前的对象扩展
const peopleNew={...peopleOld, address:'上海'}
console.log(peopleOld)
console.log(peopleNew)
js
// 原来的数组
const colorOld = ['red', 'yellow']
// 重新生成一个数组,并基于之前的数组扩展
const colorNew=[...colorOld, 'blue']
console.log(colorOld)
console.log(colorNew)
08、map函数
map()
:将原数组中的所有元素通过一个函数进行处理,并放入到一个新数组中,并返回该新数组。
js
// 举例:字符串数组 -> int数组
let arr = ['1','20','-5','3'];
arr = arr.map(s => parseInt(s));
console.log(arr)
09、reduce函数
reduce(function(), 初始值(可选))
接收一个函数(必须)和一个初始值(可选),该函数接收两个参数:
- 第一个参数是上一次reduce处理的结果
- 第二个参数是数组中要处理的下一个元素
reduce()
会从左到右依次把数组中的元素用reduce处理,并把处理的结果作为下次reduce的第一个参数。如果是 第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数
js
let arr = [1, 20, -5, 3]
// 没有初始值
let a = arr.reduce((a, b) => a+b) // 等价于 1 + 20 + (-5) + 3
let d = arr.reduce((a, b) => a*b) // 等价于 1 * 20 * (-5) * 3
// 设置初始值为1
let b = arr.reduce((a, b) => a+b, 1) // 等价于 1 + 1 + 20 + (-5) + 3
let c = arr.reduce((a, b) => a*b, 1) // 等价于 1 * 1 * 20 * (-5) * 3
console.log(a,b,c,d);