函数中的this和创建类class
一、 函数中的this
1.1 默认值
在全局作用域下,this指向全局对象,即window。(可使用globalThis属性获取全局对象)
1.1.1 常见函数
this的值跟其函数的调用者有关,严格模式下没有调用者 this 为 undefined。
函数 | this指向 |
---|---|
普通函数 | 函数的调用者,或者window |
定时器函数 | 同上 |
自调用函数 | 同上 |
对象中的方法 | 调用者对象 |
构造函数 | 实例对象 |
事件处理函数 | 事件源 |
普通函数没有明显的调用者时,this默认指向window,但是在严格模式下没有调用者时,this指向undefined。
- 严格模式 (即对代码语法要求严格的开发模式。)语法如下:
// 必须将这句代码置于 采用严格模式的作用域 的 第一句话
"use strict"
- 在严格模式下,语法要求非常严格;
– 所有变量必须定义后才能使用,也不能删除变量;
– 普通函数中的this指向undefined,不再是 window;
– 函数形参不能重名;
1.1.2 箭头函数
-
箭头函数没有自己的 this , arguments , super 或者 new.target 。
-
若在箭头函数用使用 this , this 指向的其实是作用域链的上级中的this指向。
<script>
let fn = () => {
'use strict'
return this
}
fn()
</script>
- 由于箭头函数中的this指向不明确,在事件处理函数和构造函数中,我们一般不使用箭头函数。
1.2 定义值
改变函数中的this指向。
1.2.1 call()
// 函数中的this指向 thisArg
function.call(thisArg,arg1,arg2,,,)
1.2.2 apply()
// 函数中的this指向 thisArg
function.apply(thisArg,[arg1,arg2,,,])
- 与 call() 不同之处:第二个参数只能是一个包含多个参数的数组,使用时再拆开。(和…扩展运算符功能一样)例如 :利用Math.max/min.apply() 求一个数组的最大值或最小值;
- call() 一般在继承中使用, apply() 常用于数组;
- apply 可以使用数组字面量或数组对象;
1.2.3 bind()
// 函数中的this指向 thisArg 函数并不会执行
function.bind(thisArg,arg1,arg2,,,)
// 函数执行
function.bind(thisArg)()
- bind() 与 call() 、apply() 的区别
call() 和 apply() 在使用时会立刻调用函数,同时改变this指向;而 bind() 只是会改变this,并不会立即执行函数。
二、创建类 class
类的本质就是函数。
2.1 封装
在ES6中新增了使用class创建类的方法,类声明不可以提升。
// 定义类 会自动把属性添加到类中,方法添加到其原型对象上
class 类名{ 公共 属性 / 方法 }
// 实例化对象
let obj = new 类名()
2.1.1 静态成员
使用 static 添加静态成员
<script>
class Student {
// 静态成员 static 添加成员
static college = '黑魔法学院'
static faculty = '计算机与信息工程学院'
static year = 2022
static major() {
console.log('计算机科学与技术')
}
}
// 实例化对象
let stu1 = new Student()
console.log(stu1)
// 访问静态成员 静态成员只能由构造函数访问
console.log(Student.college)
Student.major()
console.log(stu1.college) // undefiend
stu1.major() // 报错 stu1.major is not a function...
</script>
2.1.2 实例成员
直接添加实例成员
<script>
class Student {
// 实例成员 直接添加成员
college = '黑魔法学院'
faculty = '计算机与信息工程学院'
year = 2022
major() {
console.log('计算机科学与技术')
}
}
// 实例化对象
let stu1 = new Student()
console.log(stu1)
// 访问实例成员 实例成员只能由实例对象访问
console.log(stu1.college)
stu1.major()
console.log(Student.college) //undefined
Student.major() // Student.major is not a function...
</script>
2.1.3 constructor构造函数
- 类的一个特定的构造方法,在类被实例化的时候自动调用。
- 作用:接收参数,做初始化操作。
<script>
class Person {
constructor(uname, age, id) {
this.uname = uname
this.age = age
this.id = id
console.log(uname, age, id)
}
year = 2022
major() {
console.log('计算机科学与技术')
}
}
let obj1 = new Person('小摩托', 21, 'GLYB-85')
console.log(obj1)
let obj2 = new Person('大摩托', 23, '199785')
console.log(obj2)
</script>
2.2 继承
2.2.1 extends
声明一个类为另一个类的子类,并且可以继承父类的属性和方法。
// 子类没有自己的成员,继承父类的成员
class ChildClass extends ParentClass{}
2.2.2 super
调用父类的方法,this之前使用。
// 访问属性
super(arg1,arg2,,,)
// 访问方法
super.function()
<script>
class Person {
constructor(uname, age, sex) {
this.uname = uname
this.age = age
this.sex = sex
}
adress() {
console.log('地球村')
}
}
// 继承
// 当子类有自己的成员时 先用super()调用父类成员
class P1 extends Person {
constructor(uname, age, sex, id) {
super(uname, age, sex)
this.id = id
}
// 若有相同方法,采用就近原则
adress() {
console.log('中国')
super.adress()
}
}
// 实例对象
let obj1 = new P1('小摩托', 21, '女', 9785)
console.log(obj1)
obj1.adress()
let obj2 = new P1('大摩托', 23, '男', 199785)
console.log(obj2)
obj2.adress()
</script>