闭包/类与对象/解构/浏览器的 js
闭包/类与对象/解构/浏览器的 js
闭包
- 实际开发中用到的闭包
闭包形成的条件:
1.父子函数
2.子函数调用了父函数中的变量
我们来看一个案例:
{
function a(a) {
f = function (b) {
return a + b;
};
return f;
}
console.log(a(10)(20));
}
这个案例中我们声明了一个函数 a,给函数 a 传了一个参数 a,在函数 a 中我们又声明了一个方法 f,给这个函数传个参数 b,返回 a+b。最后在函数 a 中把这个 f 给返回出来。这时我们的闭包就形成了。满足了以上的两个条件,父子函数和子函数调用了父函数中的变量。当我们调用 a 函数时给函数 a 传个参数 a=10,返回出来一个函数 f,我们再给这个返回出来的函数传一个变量 b=20,返回 a+b=20。子函数如果引用了父函数中的变量,那么当父函数被调用后它的作用域不会消失,会依然存在。拿上面那个案例来说就是函数 a 被调用后他的作用域并不会消失,因为父函数 f 引用了函数 a 中的变量
-
偏函数
案例:{
pianhanshu = function (a, b) {
return function (c) {
return a + b + c;
};
};
console.log(pianhanshu(10, 20)(30));
}
这里我们把三个参数分两次传入
-
科里化函数:将参数逐个传入
{
function sum(a) {
return function (b) {
return function (c) {
return a + b + c;
};
};
}
console.log(sum(1)(4)(10));
}
使用箭头函数简化后
{
sum = a => b => c => a + b + c;
console.log(sum(1)(5)(10));
}
-
反闭包:纯函数
纯函数:函数中用到的变量全是自己的,没有*变量,如果函数内部必须要用到外部变量,通过参数传入
案例:{
let discount = 0.8;
sum = (money, discount = 1) => `该商品打完折后是${money * discount}元`;
console.log(sum(1000, discount));
}
访问器属性
看上去访问的是属性,实际上调用的是方法
案例:
{
const user_vip = {
userinfo: { id: 1, name: "Mr.fu", vip: false },
set vip(vip) {
if (vip === true || vip === false) {
this.userinfo.vip = vip;
return "非法参数";
} else {
return "非法参数";
}
},
get vip() {
return this.userinfo.vip;
},
};
user_vip.vip = true;
console.log(user_vip.vip);
}
类与对象
类
- 构造函数,创建对象专用
示例:
{
let User = function (first, second) {
this.name = first;
this.num = second;
};
let userinfo1 = new User("小夫", 613610);
let userinfo2 = new User("大熊", 613611);
console.log(userinfo1);
console.log(userinfo2);
}
给这个构造函数添加了两个自定义属性,一个是 name,一个是 num,值分别对应着这个函数传过来的两个参数,first 和 second,然后我们再创建一个变量 userinfo1 通过调用 User 函数传入两个参数来改变两个属性的值并存储保存到 userinfo1 中。New 必须要写,如果不写是无法储存的。
给 User 添加自定义方法,必须添加到他的原型对象属性上,使用 prototype
例如:
{
let User = function (first, second) {
this.name = first;
this.num = second;
};
let userinfo1 = new User("小夫", 613610);
let userinfo2 = new User("大熊", 613611);
console.log(userinfo1);
console.log(userinfo2);
User.prototype.getinfo = function () {
return `学生姓名:${this.name} 学号:${this.num}`;
};
console.log(userinfo1.getinfo());
console.log(userinfo2.getinfo());
}
静态成员:直接挂载到构造函数对象上的属性
例如:
User.status = "enable";
console.log(User.status);
私有成员:私有变量
{
let User = function (first, second, gender) {
let gender = gender;
this.name = first;
this.num = second;
};
传统的基于构造函数的类与对象,语法上非常的复杂,那么我们来了解下 ES6,class
- ES6,class
示例:
{
class User {
name = "username";
num = 123;
#gender = "male";
constructor(first, second, gender) {
this.name = first;
this.num = second;
this.#gender = gender;
}
getinfo() {
return `学员姓名:${this.name} 学号:${this.num} 性别:${this.#gender}`;
}
static school = "php.cn";
}
const User1 = new User("小夫", 613610, "男");
console.log(User1.getinfo());
}
继承 super
class Username {
name = "";
stunum = 0;
#gender = "male";
constructor(name, stunum, gender) {
this.name = name;
this.stunum = stunum;
this.#gender = gender;
}
getUserInfo() {
return `姓名:${this.name} 学号:${this.stunum} 性别:${this.#gender}`;
}
}
let user1 = new Username("Mr.fu", 613160, "男");
console.log(user1.getUserInfo());
class Userinfo extends Username {
constructor(name, stunum, gender, school) {
super(name, stunum, gender);
this.school = school;
}
getUserInfo() {
return `${super.getUserInfo()} 学校:${this.school}`;
}
}
let user2 = new Userinfo("Mr,fu", 613160, "男", "");
console.log(user2.getUserInfo());
在类中也可以使用访问器属性
例如:
class Vip {
#vip = false;
set vip(vip) {
if (vip === true || vip === false) {
this.#vip = vip;
} else {
console.log(`非法参数`);
}
}
get vip() {
return this.#vip;
}
}
const vip = new Vip();
vip.vip = true;
console.log(vip.vip);
解构/赋值
- 数组解构
let [number, name] = [613160, "Mr.fu"];
console.log(number,name);
参数不足
[number, name, age = 18] = [613160, "Mr.fu"];
console.log(number,name,age);
参数过多…
let [a, b, ...other] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(a, b, other);
两数交换
let x = 10;
let y = 20;
[x, y] = [y, x];
console.log(x, y);
对象解构
对象模板=对象字面量
let { name, number, school } = {
name: "Mr.fu",
number: 613160,
school: "php.cn",
};
如果再次改变数据,一定要记得加(),因为{}不能充当左值
({ name, number, school }) = {
name: "Mr.zhu",
number: 613100,
school: "php.cn",
};
当左边模板中的变量出现命名冲突,使用别名解决
let { name:username, number:usernumber, school:userschool } = {
name: "Mr.fu",
number: 613160,
school: "php.cn",
};
console.log(username,usernumber,userschool);
克隆对象
let { ...user } = {
name: "Mr.fu",
number: 613160,
school: "php.cn",
};
用对象解构传参
function sum({name,number,school}){
console.log(name,number,school);
}
sum({
name: "Mr.fu",
number: 613160,
school: "php.cn",
})
JS 引入与获取 DOM 元素
-
JS 引入
浏览器是解析 html 的,在 html 中,js 代码应该写在 js 标签内
例如:<!DOCTYPE html>
<html lang="zh-CN">
<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>Document</title>
<script>
function setBg(btn) {
document.body.style.backgroundColor = "lightgreen";
btn.style.backgroundColor = "yellow";
btn.textContent = "save sucess";
}
</script>
</head>
<body>
<button onclick="setBg(this)">btn1</button>
</body>
</html>
js 的引入和 css 非常相似,也可以从外部引入 js 文件
<!DOCTYPE html>
<html lang="zh-CN">
<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</title>
<script src="./demo9.js"></script>
</head>
<body>
<button onclick="setBg(this)">btn1</button>
</body>
</html>
- 获取 dom 元素
示例:
<!DOCTYPE html>
<html lang="zh-CN">
<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>Document</title>
</head>
<body>
<div class="list">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<div class="item">item4</div>
<div class="item">item5</div>
<div class="item">item6</div>
<div class="item">item7</div>
</div>
<button onclick="setBg()">点击全部变色①</button>
<button onclick="setBg_1()">点击给第一个加个背景</button>
<button onclick="setBg_2()">点击给第二个加个背景</button>
<button onclick="setBg_rainbow()">点击变为彩虹色</button>
</body>
<script>
const item = document.querySelectorAll(".list>.item");
console.log(item);
function setBg() {
for (i = 0; i < item.length; i++) {
item[i].style.backgroundColor = "red";
}
}
const item_1 = document.querySelector(".list>.item");
function setBg_1() {
item_1.style.backgroundColor = "green";
}
const item_2 = document.querySelector(".list>.item:nth-of-type(2)");
function setBg_2() {
item_2.style.backgroundColor = "blue";
}
function setBg_rainbow() {
item[0].style.backgroundColor = "#FF0000";
item[1].style.backgroundColor = "#FF7F00";
item[2].style.backgroundColor = "#FFFF00";
item[3].style.backgroundColor = "#00FF00";
item[4].style.backgroundColor = "#00FFFF";
item[5].style.backgroundColor = "#0000FF";
item[6].style.backgroundColor = "#8B00FF";
}
</script>
</html>
推荐阅读
-
python基础(13):函数名的使用、第一类对象、闭包、迭代器
-
利用js的闭包原理做对象封装及调用方法
-
JS继承与闭包及JS实现继承的三种方式
-
JS的闭包与定时器
-
闭包的原理与经典应用场景,访问器属性,类与对象的创建与成员引用,数组与对象的解构过程与经典案例,JS引入到浏览器中的的方法及获取DOM元素的两个API
-
js闭包/类创建/解构赋值
-
闭包/类与对象/解构/浏览器的 js
-
闭包的原理与经典应用场景 、访问器属性、类与对象的创建与成员引用 、数组与对象的解构、JS引入到浏览器中的的方法
-
闭包的原理与经典应用场景,访问器属性,类与对象的创建与成员引用,数组与对象的解构过程与经典案例,JS引入到浏览器中的的方法及获取DOM元素的两个API
-
javascript中的闭包原理以及数组与对象的学习