后盾人JS--继承
继承是原型的继承
<!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>
let f = {}
console.log(f.__proto__)
function User() {
User.prototype.name = function () {
console.log("user.name")
}
}
function Admin() { }
// Admin.prototype.__proto__ = User.prototype
Admin.prototype = Object.create(User.prototype)
Admin.prototype.role = function () {
console.log("admin.role")
}
function Member() { }
Member.prototype = Object.create(User.prototype)
Member.prototype.role = function () {
console.log("member.role")
}
let a = new Admin()
a.role()
</script>
</body>
</html>
两种方式都可以实现继承
禁止constructor被遍历
有的时候不希望constructor被遍历
<!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 Admin(){
Admin.prototype = Object.create(User.prototype)
console.log(Object.getOwnPropertyDescriptor(Admin.prototype))
Object.defineProperty(Admin.prototype,'construct',{
value:Admin
})
Admin.prototype.role = function(){
console.log("admin.role")
}
let a = new Admin()
for(const key in a)
{
console.log(key)
}
}
</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 User(){
User.prototype.show = function(){
console.log("user.name")
}
}
User.prototype.site = function(){
return "后盾人"
}
function Admin(){}
Admin.prototype = Object.create(User.prototype)
Admin.prototype.constructor = Admin
Admin.prototype.show = function(){
console.log(User.prototype.site() + "admin.show")
}
let hd = new Admin()
hd.show()
</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 User(){}
User.prototype.show = function(){
console.log(this.description())
}
function Admin(){}
Admin.prototype = Object.create(User.prototype)
Admin.prototype.description = function(){
return "管理员在此"
}
function Member(){}
Member.prototype = Object.create(User.prototype)
Member.prototype.description = function(){
return "我是会员"
}
function Enterprise(){}
Enterprise.prototype = Object.create(User.prototype)
Enterprise.prototype.description = function(){
return "企业账户"
}
for(const obj of [new Admin(),new Member(),new Enterprise()]){
obj.show()
//假如没有多态
if(obj instanceof Admin){
console.log(obj.showAdmin())
}
}
</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>
let hd = {
name: "后盾人",
view() {
console.log(this.name)
}
}
hd.view()
function User(name, age) {
this.name = name
this.age = age
}
User.prototype.show = function () {
console.log(this.name, this.age)
}
function Admin(...args) {
User.apply(this, args)
}
Admin.prototype = Object.create(User.prototype)
let xj = new Admin("向军", 18)
xj.show()
function Member(...args) {
User.apply(this, args)
}
Member.prototype = Object.create(User.prototype)
let lisi = new Member("李四", 19)
lisi.show()
</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 extend(sub,sup){
sub.prototype = Object.create(sup.prototype)
Object.defineProperty(sub.prototype,"constructor",{
value:sub,
enumerable:false
})
}
function User(name,age){
this.name = name
this.age = age
}
User.prototype.show = function(){
console.log(this.name,this.age)
}
function Admin(...args){
User.apply(this,args)
}
extend(Admin,User)
let admin = new Admin('向军',19)
admin.show()
function Member(...args){
User.apply(this,args)
}
extend(Member,User)
let member = new Member('李四',23)
member.show()
// Member.prototype = Object.create(User.prototype)
// Object.defineProperty(Member.prototype,"constructor",{
// value:Member,
// enumerable:false
// })
</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 User(name,age){
this.name = name
this.age = age
}
User.prototype.show = function(){
console.log(this.name,this.age)
}
function admin(name,age){
const instance = Object.create(User.prototype)
User.call(instance,name,age)
instance.role = function(){
console.log("role")
}
return instance
}
let hd = admin("向军",19)
hd.show()
hd.role()
// let admin = new Admin('向军',19)
// admin.show()
// function Member(...args){
// User.apply(this,args)
// }
// extend(Member,User)
// let member = new Member('李四',23)
// member.show()
// Member.prototype = Object.create(User.prototype)
// Object.defineProperty(Member.prototype,"constructor",{
// value:Member,
// enumerable:false
// })
</script>
</body>
</html>
mixin实现多继承
// 定义一些 mixin 对象
const canEat = {
eat() {
console.log('I can eat.');
}
};
const canWalk = {
walk() {
console.log('I can walk.');
}
};
const canSwim = {
swim() {
console.log('I can swim.');
}
};
// 定义一个基础类
class Person {}
// 定义一个混入函数
function mixin(target, ...sources) {
Object.assign(target.prototype, ...sources);
}
// 进行混入操作
mixin(Person, canEat, canWalk, canSwim);
// 创建 Person 实例
const person = new Person();
// 调用混入的方法
person.eat();
person.walk();
person.swim();
使用工厂函数混入:
// 定义一些 mixin 函数
function canFly() {
return {
fly() {
console.log('I can fly.');
}
};
}
function canClimb() {
return {
climb() {
console.log('I can climb.');
}
};
}
// 定义一个基础类
class Animal {}
// 定义一个工厂函数进行混入
function createMixinAnimal(...mixins) {
class MixedAnimal extends Animal {}
mixins.forEach(mixin => {
Object.assign(MixedAnimal.prototype, mixin());
});
return MixedAnimal;
}
// 创建一个混入了 canFly 和 canClimb 的新类
const FlyingClimbingAnimal = createMixinAnimal(canFly, canClimb);
// 创建实例
const animal = new FlyingClimbingAnimal();
// 调用混入的方法
animal.fly();
animal.climb();
mixin的内部继承与super关键字
功能类也可以实现继承
<!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 extend(sub,sup){
sub.prototype = Object.create(sup.prototype)
Object.defineProperty(sub.prototype,"constructor",{
value:sub,
enumerable:false
})
}
const Address = {
getAddress(){
console.log("获取收货地址")
}
}
const Request = {
ajax(){
return "请求后台"
}
}
const Credit = {
__proto__:Request,
total(){
console.log(super.ajax()+"积分统计")
}
}
function User(name,age){
this.name = name
this.age = age
}
User.prototype.show = function(){
console.log(this.name,this.age)
}
function Admin(name,age){
User.call(this,name,age)
}
extend(Admin,User)
Admin.prototype = Object.assign(Admin.prototype,Request,Credit)
let admin = new Admin("向军",19)
admin.show()
admin.ajax()
admin.total()
function Member(name,age){
User.call(this,name,age)
}
extend(Member,User)
// Member.prototype = Object.assign(Admin.prototype,Request,Credit)
// let lisi = new Member("李四",22)
// lisi.getAddress()
</script>
</body>
</html>
Tab选项卡显示效果基类开发
<!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>
<main class="tab2">
<nav>
<a href="javascript:;">后盾人</a>
<a href="javascript:;">hdcms</a>
</nav>
<section>1</section>
<section>2</section>
</main>
<script>
function extend(sub,sup){
sub.prototype = Object.create(sup.prototype)
sub.prototype.constructor = sub
}
function Animation(){}
Animation.prototype.show = function(){
this.style.display = "block"
}
Animation.prototype.hide = function(){
this.style.display = "none"
}
Animation.prototype.background = function(color){
this.style.backgroundColor = color
}
// let tab = document.querySelector('.tab')
// Animation.prototype.background.call(tab,"red")
</script>
</body>
</html>
好用的TAB业务管理类
<!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>
<main class="tab1">
<nav>
<a href="javascript:;">后盾人</a>
<a href="javascript:;">hdcms</a>
</nav>
<section>1</section>
<section>2</section>
</main>
<main class="tab2">
<nav>
<a href="javascript:;">后盾人</a>
<a href="javascript:;">hdcms</a>
</nav>
<section>1</section>
<section>2</section>
</main>
<script>
function extend(sub,sup){
sub.prototype = Object.create(sup.prototype)
sub.prototype.constructor = sub
}
function Animation(){}
Animation.prototype.show = function(){
this.style.display = "block"
}
Animation.prototype.hide = function(){
this.style.display = "none"
}
Animation.prototype.background = function(color){
this.style.backgroundColor = color
}
// let tab = document.querySelector('.tab')
// Animation.prototype.background.call(tab,"red")
function Tab(el){
this.tab = document.querySelector(el)
this.links = this.tab.querySelectorAll('a')
this.sections = this.tab.querySelectorAll('section')
}
extend(Tab,Animation)
Tab.prototype.run = function(){
this.bindEvent()
this.reset()
this.action(0)
}
Tab.prototype.bindEvent = function(){
this.links.forEach((el,i) => {
el.addEventListener("click",()=>{
this.reset()
this.action(i)
})
});
}
Tab.prototype.action =function(i){
this.background.call(this.links[i],"#e67e22")
this.show.call(this.sections[i])
}
Tab.prototype.reset =function(){
this.links.forEach((el,i)=>{
this.background.call(this.links[i],"#95a5a6")
this.hide.call(this.sections[i])
})
}
new Tab('.tab2').run()
</script>
</body>
</html>
也可以通过设置默认参数来进行更多的设置,让自由度更高