使用 let 代替 var。
let 的优点:
{ var str = 'hello world';}
console.log(str); // hello world
{ let str = 'hello world';}
console.log(str); // 报错:str is not defined
console.log(str);
var str = 'hello world'; // undefined
console.log(str);
let str = 'hello world'; // 报错:Cannot access 'str' before initialization
var num = 10;
var num = 20;
console.log(num); // 20
let num = 10;
let num = 20;
console.log(num); // 报错:Identifier 'num' has already been declared\n
总的来说,let 会让变量声明更加规范。
使用 const 定义 常量(即不变的值)。
定义之后不可以修改:
const num = 10;
num = 20;
console.log(num); // 报错:Assignment to constant variable.
使用 const 声明的几种情况:
const PI = 3.14;\nconsole.log(PI); // 3.14
const fun = function (a, b) {
return a + b;
}
fun(1, 1);
function getStundent() {
return {
name: 'Lulu',
age: 20
}
}
// 对象声明可以使用常量
const student = getStundent();
// 虽然是常量,但是对象里面的属性可以改变
student.name = 'Mary';
console.log(student.name); // 'Mary'
const express = require('express');
语法:
// 反引号 ``
let str = `hello world`;
console.log(str); // hello world
优点:
let str = `hello
world`;
console.log(str);
let year = "2023";
let month = "08";
let date = "08";
// 拼接成 "2023年08月08日"
let result = `${year}年${month}月${date}日`
console.log(result); // 2023年08月08日
// let n = 10;
// let m = 20;
let [n, m] = [10, 20];
console.log(n); // 10
console.log(m); // 20
示例:交换 n 和 m 的值。
let n = 10;
let m = 20;
// 交换
[n, m] = [m, n];
console.log(n); // 20
console.log(m); // 10
// let obj = {name: "xiaoming", age: 10};
// let name = obj.name;
// let age = obj.name;
let { name, age } = { name: "xiaoming", age: 10 };
// 如果颠倒 name,age的顺序并不会影响结果:
// let { age, name } = { name: "xiaoming", age: 10 };
console.log(name); // xiaoming
console.log(age); // 10
// function getName(obj) {
// return obj.name
//}
function getName({name, age}) {
// name ==> obj.name
// age ==> obj.age
return name
}
let result = getName({name: 'xiaoming', age: 10});
console.log(result); // xiaoming
ES2015 的语法可以为函数的参数设置默认值:
function fun(x = 10, y = 20) {
return x + y;
}
fun(); // 30
fun(1); // 21
fun(10, 20); // 30
function fun(x, y) {
console.log(x); // undefined
console.log(y); // undefined
return x + y;
}
let result = fun();
console.log(result); // NaN
(function () {
let a = 10;
let b = 20;
console.log(a + b);
})();
// 30
功能:封装代码。
特点:
作用域链:
|-window
| |-str
| |-fun1
| | |-str
| | |-num
| | |-fun2
| | | |-str
| | | |-num
let str = "hello";
function fun1() {
let str = "world";
let num = 10;
function fun2() {
let str = 'fun2';
let num = 20;
console.log(str); // fun2
console.log(num); // 20
}
fun2();
console.log(str); // world
console.log(num); // 10
}
fun1();
console.log(str); // hello
示例1:想要在 fun1 的外部打印 fun2 的结果。
function fun1() {
function fun2() {
console.log("I'm fun2");
}
}
利用 return在函数外部调用 fun2。
function fun1() {
function fun2() {
console.log("I'm fun2");
}
// 闭包的精华:return
return fun2;
}
const f = fun1();
f(); // I'm fun2
示例2:想要在 fun1 的外部求和。
function fun1() {
let n = 10;
let m = 20;
function fun2() {
return n + m;
}
return fun2;
}
const f = fun1(); // fun1的运行结果是fun2
let result = f();
console.log(result); // 30
代码封装:
ES5 的一个模块化的语法。
const module = (function () {
let a = 10;
let b = 20;
function add() {
return a + b;
}
return add;
})();
作用: 简化写法。
const add = function (x) {
return x * x;
};
// 简化
const add = (x) => {
return x * x;
};
// 简化
// 参数 返回值
const fun = x => x * x;
示例:每秒输出一次名字。
const cat = {
name: "miaomiao",
sayName() {
let self = this;
setInterval(function () {
// window调用的setInterval
// this 指向 window,所以需要提前保存
console.log(self.name);
}, 1000)
},
...
// 使用箭头函数:
sayName() {
// 箭头函数:在哪里定义,this 就指向谁
setInterval(() => {
// this 指向 cat
console.log(this.name);
}, 1000);
},
...
};
cat.sayName(); // miaomiao
箭头函数和普通函数的 this 指向不同:
- 普通函数指向的是 调用该函数的对象;
- 箭头函数是 在哪里定义,this 就指向谁。
面向对象是一种编程思想,这种编程思想可以当做一个学科来研究。
除了 JavaScript,例如 C++、Java、Python、PHP 等等编程语言都可以使用这种面向对象的编程思想来开发应用程序。
构造函数的函数名,首字母大写;
构造函数是用来创建对象用的。
语法:function Dog(){}
// 构造函数Dog
function Dog(name, age) {
this.name = name;
this.age = age;
}
let dog = new Dog("wangwang", 2); // 创建了一个对象,狗类的实例:wangwang
console.log(dog.name); // wangwang
通过设置构造函数的 prototype 属性,可以扩展构造函数生成的对象。
通过原型对象,为构造函数生成的对象赋予新的方法。
function Dog(name, age) {
this.name = name;
this.age = age;
}
// 给 Dog.prototype 添加方法
Dog.prototype.sayName = function () {
console.log(this.name);
};
let dog1 = new Dog("wangwang", 2);
let dog2 = new Dog("jimmy", 6);
// 所有 Dog 的实例都可以使用 sayName 方法
dog1.sayName(); // wangwang
dog2.sayName(); // jimmy
将该构造函数 Dog 的原型指向另一个构造函数 Animal 的实例,则 所有 Dog 的实例都可以使用 Animal 上的变量和方法。
Dog.prototype = new Animal()
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function () {
console.log(`你好,我是${this.name}`);
};
function Dog(name) {
this.name = name;
}
// 继承的精华 => 就在这句
Dog.prototype = new Animal();
var dog = new Dog("wangwang");
dog.sayName(); // 你好,我是wangwang
语法:
class 构造函数名字 {
// 使用constructor 声明属性
constructor() {…}
}
class Dog {
// constructor 声明属性:
constructor(name, age) {
this.name = name;
this.age = age;
}
// 方法在 constructor 下面写:
sayName() {
console.log(`我是${this.name}`);
}
}
let dog = new Dog("wangwang", 2);
dog.sayName(); // 我是wangwang
语法:extends 关键字 + super。
示例1:让 Dog 继承 Animal。
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(`我是${this.name}`);
}
}
// 使用 extends关键字:让 Dog 继承 Animal
class Dog extends Animal {}
let dog = new Dog("wangwang");
dog.sayName(); // 我是wangwang
示例2:让 Dog 继承 Animal 中的一些属性,然后再声明自身所需要的属性。
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
console.log(`我是${this.name}`);
}
}
// 使用 extends关键字:让 Dog 继承 Animal
class Dog extends Animal {
constructor(name, age, id) {
// 父级的属性: super关键字
super(name, age);
// 子级的属性就用 this 关键字声明
this.id = id;
}
// 方法:
getId() {
console.log(`我的编码是${this.id}`);
}
}
let dog = new Dog("wangwang", 2, 1234567);
console.log(dog.name, dog.age, dog.id); // wangwang, 2, 1234567
dog.sayName(); // 我是wangwang
dog. getId(); // 我的编码是1234567
DOM:是一套标准编程接口。
我们通过 DOM 这套接口来操作HTML元素。
网页效果:操作元素节点、属性节点、文本节点,以及修改元素的样式。
DOM 通过 document 对象,为开发者提供了大量的接口(API)来操作 DOM 树。
<h1 id="title">hello world</h1>
let h1 = document.getElementById("title");
console.log(h1);
<button>123</button>
<button>456</button>
<button>789</button>
let btns = document.getElementsByClassName("btn");
console.log(btns);
let h1 = document.querySelector("#title");
h1.innerHTML = "你好世界";
let btns = document.querySelectorAll(".btn");
for (let i in btns) {
btns[i].innerHTML = "test";
}
let a = document.querySelector("#a");
a.innerHTML = "链接";
let btn = document.querySelector("button");
// 事件监听函数
btn.onclick = function () {
console.log("hello btn");
};
let box = document.querySelector(".box");
// 鼠标移入元素
box.onmouseenter = function () {
console.log("hello");
};
let box = document.querySelector(".box");
// 鼠标移出元素
box.onmouseleave = function () {
console.log("bye");
};
语法:
element.style.color = “red”
element.style.backgroundColor = “pink”
通过 click、mouseenter、mouseleave 事件控制样式。
示例1:设置 box 的样式。
let box = document.querySelector("#box");
// 鼠标移入元素
box.onmouseenter = function () {
this.style.backgroundColor = "blue";
};
// 鼠标移出元素
box.onmouseleave = function () {
this.style.backgroundColor = "red";
};
示例2:通过点击 button 设置 box 的样式:
let btn = document.querySelector("#btn");
let box = document.querySelector("#box");
// 点击事件监听函数
btn.onclick = function () {
box.style.backgroundColor = "yellow";
};
语法:
element.src = "images/1.png";
element.id = "wrapper";
示例:点击数字列表切换图片。
// 图片列表
let imgList = ["images/1.png", "images/2.png", "images/3.png"];
let btnList = document.querySelectorAll("btn");
let imgBox = document.querySelector("#box");
for(let i in btnList){
btnList[i].onclick = function(){
imgBox.src = imgList[i];
}
}
语法:
element.className = "red";
示例:点击 li ,设置激活的背景色。
.active {
background-color: red;
}
let liList = document.querySelectorAll("li");
for (let i in liList) {
liList[i].onclick = function () {
if(this.className === 'active'){
this.className = ''
return;
}
this.className = 'active';
};
}