Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:
作用域有三种:全局作用域、函数作用域、块作用域
1.函数作用域:默认,不可删除,由全局对象调用
let site = "你好";
console.log(site);
2.函数作用域
<script>
// site是声明在函数外部的全局变量
let site = "你好";
console.log(site);
function getSite() {
// 在函数内部可以访问到外部的全局变量
let site = "再见";
// 这里要返回一个叫site的变量
// 有一个查询的过程, 先在自身的作用域找一个有没有一个叫site
// 如果有则直接返回它
// 如果函数中没有这个site,则自动函数的上一级作用域中去查看site
// 全局正好有一个site,于是就返回了全局的site
// 内部的site ---> 到它的上一级作用域中去查找
// 上面的查询变量的过程,就是是一个链式查询的一个过程,称为:作用域链
// 私有成员,仅限在当前作用内访问, 外部不可见
let domain = "php.cn";
return `${site} [ ${domain} ]`;
}
console.log(getSite());
console.log(domain);
</script>
3.块作用域
// 使用{}会形成块作用域
{
let a = 1;
const C = "c";
//var:不支持块作用域
var a = 2;
var C = "c";
}
console.log(a, B);
let c = 100;
function sum(a, b) {
// return a + b;
// 现在已经产生了闭包了
// 函数中的变量按来源有二种类型
// 1. 形参: a, b , 这是函数自有的
// 2. 自由变量: c, c并不是函数自有的
// 当前的函数可以访问到上一级/外部的自由变量
// 闭包: 能够访问自由变量的函数
// 自由变量,函数参数以外的变量
// 理论上讲,所有函数都是闭包
return a + b + c;
}
console.log(sum(4, 5));
通过闭包来访问内部的私有变量
<script>
function demo() {
// 私有变量
let email = "a@qq.com";
return function d() {
// 对于这个子函数来说,email就是它的自由变量
return email;
};
}
let f = demo();
console.log(f());
</script>
// 构造函数来模拟类(对象的模板)
function User(name, email) {
this.name = name;
this.email = email;
// show()输出属性
this.show = function () {
return { name: this.name, email: this.email };
};
}
// 构造函数对象的原型对象上的成员,可以被所有实例所共享
User.prototype.show = function () {
return { name: this.name, email: this.email };
};
const user = new User("wsc", "sa@qq.com");
console.log(user);
console.log(user.show());
<script>
class User {
// 构造方法:用于初始化对象
constructor(name, email) {
this.name = name;
this.email = email;
}
// 原型方法:通过对象调用
show() {
return { name: this.name, email: this.email, age: this.#age };
}
// 静态方法: 不需要实例化(new class),直接用类来调用
static fetch() {
return "static function";
}
static fetch1() {
// 静态成员中的this表示的就是当前的类
return this.userName;
}
// 静态属性、变量
static userName = "wp";
// 私有成员
#age = 50;
// 还可以声明访问器属性: 伪装成属性的方法,有get,set
// 使用访问器属性来访问私有成员
get age() {
return this.#age;
}
set age(value) {
if (value >= 18 && value < 60) this.#age = value;
else console.log("年龄非法");
}
}
const user = new User("wsc", "sa@qq.com");
console.log(user);
console.log(user.show());
// 静态方法直接用类调用
console.log(User.fetch());
console.log(User.fetch1());
console.log("my age = ", user.age);
user.age = 160;
console.log("my age = ", user.age);
user.age = 32;
console.log("my age = ", user.age);
//继承,通常是对父类进行一些扩展(添加一些新的属性或方法)
class Child extends User {
constructor(name, email, gender) {
// 第一步必须将父类的构造方法先执行一下,否则this无法使用
super(name, email);
// 第二步给子类的新成中去初始化
this.gender = gender;
}
// 父类的原型方法
show() {
return { name: this.name, email: this.email, gender: this.gender };
}
}
const child = new Child("ww", "aa@qq.com", "男");
console.log(child.show());
</script>