JS 构造函数与类
一、构造函数
JS 没有“类”(class),通过“构造函数”来实现
JS 是基于“原型继承”实现面对对象编程
1.类中成员
- 属性:实例(对象):声明在构造方法中
- 方法:实例共享:声明在原型(prototype)
- 静态:函数(类)访问:直接挂载到构造方法中
const fn = function () { }
console.log(typeof fn)
//instanceof:判断某个对象是否是某个类的实例
console.log(fn instanceof Object)
//true ,函数也是对象,是对象的一种
fn.site = 'php.cn'
fn.hello = function () {
return 'Hello ' + this.site
}
console.log(fn.site)
console.log(fn.hello())
console.log('------------------')
//任何函数都有一个“原型”属性,是一个对象{}
console.log(fn.prototype, typeof fn.prototype)
//JS是基于原型实现继承,所以原型对象上的成员可以被所有类实例共享
console.log('------------------')
2. 构造函数
专用于创建对象(实例)
声明
1.函数名首字母应该大写(大驼峰):行为规范请遵守
2.禁止用箭头函数声明:箭头函数没有自己的this
let User = function (uname, email) {
//创建新对象,JS自动完成
//let this = new User()
//添加新对象
//(1)属性
this.uname = uname
this.email = email
//返回this,JS自动完成
//return this
}
// (2) 方法,应该被所有对象所共享,prototype
User.prototype.say = function () {
return `${this.uname}:${this.email}`
}
//(3)静态成员
User.nation = 'CHINA'
调用
//new:控制函数内部的this指向,指向当前对象,否则全局
const user = new User('老马', 'nx99@qq.com')
// 1. 访问属性
console.log(user.uname, user.email)
console.table(user)
// 2. 访问方法
/**
* * 原型属性(prototype)
* * 任何函数都有原型属性:`prototype`
* * 原型属性仍然是一个对象
* * 声明在原型中的成员,被全部实例共享
*/
console.log(user.say())
//new class
const user1 = new User('admin', 'admin@qq.com')
console.log(user1.say())
// 3. 访问静态成员,不需要实例化
console.log(User.nation)
3. 通过“原型属性”实现继承
//子类,它是User类的子类
//这里的: “类” === “构造函数”
//SEX是子类独有的,扩展了父类功能
const Child = function (uname, email, sex) {
//继承父类
return new User(uname, email)
}
//当前类继承了User
Child.prototype = User.prototype
const child = new Child('小龙女', 'xln@qq.com')
console.table(child)
console.log(child.say())
二、class类
1.类声明
let User = class {
//构造函数:(1)声明属性
constructor(uname, email) {
this.uname = uname
this.email = email
}
//(2)方法
say() {
return `${this.uname}:${this.email}`
}
//(3) 静态属性
static nation = 'CHINA'
}
2.类的实例化
const user = new User('小龙女', 'xlv@qq.com')
console.log(user.say())
console.table(user)
console.log(User.nation)
console.log('---------继承----------')
3.继承
class Child extends User {
constructor(uname, email, sex) {
//super 调用父类成员
super(uname, email)
//子类扩展类型
this.sex = sex
}
say() {
//super.say()调用 父类中的say()
return `${super.say()},${this.sex}`
}
}
const child = new Child('杨过', 'nx33@qq.com', '女')
console.table(child)
4.在类中使用“访问器属性”
console.log('---------访问器属性----------')
const Stu = class {
//私有属性:在属性前加 #
#age = 18
//访问器属性
//1. 读:获取器
get age() {
return this.#age
}
//2. 写:设置器
set age(age) {
if (age >= 18 && age <= 100) {
this.#age = age
} else {
console.log('年龄必须在:18-100岁之间!')
}
}
}
let stu = new Stu()
console.log('age = ',stu.age)
stu.age=30
console.log('age = ',stu.age)