严格模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 开启严格模式
"use strict"
// 不适用var关键字
// num = 10;
function fun () {
console.log(this);
}
fun();
// 普通函数this在非严格模式下指向window,严格模式下指向undefined
</script>
</body>
</html>
高阶函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 满足其中之一
// 函数作为参数(参数是函数)
// 函数作为返回值
function fun1(fun) {
fun();
}
function fun2() {
console.log("参数");
}
// 函数作为参数
fun1(fun2);
// 函数作为返回值
function fun3(){
return function(){
console.log("函数作为返回值");
}
}
fun3()();
</script>
</body>
</html>
闭包
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 闭包:内部函数访问外部函数的参数或变量
// 内部函数访问外部函数的作用域,所形成的词法环境叫做闭包
// 闭包特点:
// 1.函数嵌套函数
// 2.内部函数访问外部函数的参数或变量
// 3.函数中的变量会长期驻扎在内存中
function fun1(a, b) {
// 局部变量
var num1 = 10;
function fun2() {
// 内部函数访问外部函数的变量
console.log(num1);
// 内部函数访问外部函数的参数
console.log(a + b);
}
return fun2();
}
fun1(1, 2);
</script>
</body>
</html>
闭包的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul {
margin: 0;
padding: 0;
list-style: none;
width: 500px;
margin: 50px auto 0;
display: flex;
}
li {
box-sizing: border-box;
width: 100px;
height: 30px;
line-height: 30px;
border: 1px solid #ccc;
text-align: center;
}
.active-li {
background-color: red;
}
.content {
box-sizing: border-box;
width: 500px;
height: 400px;
margin: 0 auto;
border: 1px solid #ccc;
position: relative;
}
.content div {
position: absolute;
left: 0;
top: 0;
display: none;
}
.content .active-div {
display: block;
}
</style>
</head>
<body>
<ul>
<li class="active-li">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<div class="content">
<div class="active-div">1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<script>
var list = document.querySelectorAll("li");
var box = document.querySelectorAll(".content div");
for (var i = 0; i < list.length; i++) {
// 形成闭包环境
(function(index) {
list[index].onclick = function () {
// 排他
sibling(list);
sibling(box);
this.className = "active-li";
box[index].classList = "active-div";
}
})(i);
}
function sibling(ele) {
for (var i = 0; i < ele.length; i++) {
ele[i].className = "";
}
}
</script>
</body>
</html>
递归
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 递归:函数内部访问函数本身,这个函数就是递归函数(自己调用自己)
// 求n的阶乘
function fun(n) {
if (n == 1) {
return 1;
} else {
return n * fun(n - 1);
}
}
console.log(fun(5));
// 5 * fun(4)
// 5 * 4 * fun(3)
// 5 * 4 * 3 * fun(2)
// 5*4*3*2*fun(1)
// 斐波那契数列
// 1 1 2 3 5 8 13 21 34 55 89 144 ...
function fibonacci(n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
console.log(fibonacci(8));
// f(4) + f(3)
// f(3) + f(2) + f(2) + f(1)
// f(2) + f(1) + 1+1+1
// 1+1+1+1+1
</script>
</body>
</html>
赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 数据类型
// 基本数据类型
// string boolean undefined number null
// 引用数据类型
// object array function Date Math RegExp...
// 数据类型的存储
// 赋值(地址传递)
var arr = [1, 2, 3, 4, 5];
var arr2 = arr;
arr[1] = 0;
console.log(arr);
console.log(arr2);
// 当修改其中一个内容的时候,两个都会改变
</script>
</body>
</html>
浅拷贝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 浅拷贝 Object.asign()
var obj = {
name:"小明",
age:20,
hobby:["游泳", "打球", "睡觉"]
}
var copyObj = {
usname:"小红",
sex:"男"
}
var newobj = Object.assign(copyObj,obj);
newobj.name = "zhangsan";
console.log(newobj);
console.log(copyObj);
console.log(obj);
// 改变新拷贝的对象
newobj.name = "zhangsan";
// 修改新对象的深层次的引用数据类型时
newobj.hobby[2] = "写作业";
console.log(newobj); // 新拷贝的对象
console.log(copyObj); // 目标对象
console.log(obj); // 原对象也会跟着改变
</script>
</body>
</html>
深拷贝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var obj = {
name:"小明",
age:20,
hobby:["游泳", "打球", "睡觉"],
son: {
sname: "lisi",
age: 3
}
}
// 实现深拷贝
// JSON
// 1.将对象转为 json 字符串 JSON.stringify()
var str = JSON.stringify(obj);
console.log(str);
// 2.将json字符串再转回对象 JSON.parse()
var newobj = JSON.parse(str);
// 修改其中一个
newobj.name = "小红";
newobj.son.sname = "zhangsan";
console.log(newobj);
console.log(obj);
</script>
</body>
</html>
手写递归实现深拷贝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var obj = {
name:"小明",
age:20,
// 引用数据类型
hobby:["游泳", "打球", "睡觉"],
son: {
sname: "lisi",
age: 3
}
}
var arr = [1, 2, 3, 4, 5];
console.log(arr);
for (var k in arr) {
console.log("k" + k);
console.log("value" + arr[k]);
}
// 封装深拷贝
function deepCopy(newObj, oldObj) {
// 遍历旧对象
for (var k in oldObj) {
var item = oldObj[k];
// 判断每个属性的数据类型 instanceof
if (item instanceof Array) {
// 数组处理方法
newObj[k] = [];
// 递归调用
deepCopy(newObj[k], item);
} else if (item instanceof Object) {
// 对象处理方法
newObj[k] = {};
deepCopy(newObj[k], item);
} else {
// 基本数据类型处理方法 直接赋值
newObj[k] = item;
}
}
return newObj;
}
var newObj = deepCopy({}, obj);
console.log(newObj);
newObj.name = "小红";
newObj.son.sname = "张三";
console.log(newObj);
console.log(obj);
</script>
</body>
</html>
class类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 创建类
class Person {
// 公共属性
constructor(name, age) {
this.name = name;
this.age = age;
}
// 公共方法
sayHi() {
console.log(this.name + "说nihao");
}
}
// 根据类实例化对象
var person1 = new Person("小明", 20);
console.log(person1);
person1.sayHi();
</script>
</body>
</html>
类的继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// extends 类的继承
class Father {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() {
console.log("你好");
}
}
class Son extends Father {
constructor(name, age, height) {
// 调用父类的构造函数
super(name, age);
// 再写自己独有的属性
this.height = height;
}
}
var son1 = new Son("zhangsan", 20, 180);
console.log(son1);
son1.sayHi();
</script>
</body>
</html>
定时器传递参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 定时器传递参数
// 封装函数
function fun(num) {
console.log(num);
}
setInterval(function () {
fun(1);
}, 1000);
</script>
</body>
</html>