构造函数、函数继承的综合应用
1、构造函数详解
- 我们了解了对象的创建方式
- 我们的面向对象就是要么能直接得到一个对象
- 要么就弄出一个能创造对象的东西,我们自己创造对象
- 我们的构造函数就能创造对象,所以接下来我们就详细聊聊 构造函数
(1)构造函数的基本使用
-
和普通函数一样,只不过 调用的时候要和 new 连用,不然就是一个普通函数调用
function Person() {} var o1 = new Person() // 能得到一个空对象 var o2 = Person() // 什么也得不到,这个就是普通函数调用
- 注意: 不写 new 的时候就是普通函数调用,没有创造对象的能力
-
首字母大写
function person() {} var o1 = new person() // 能得到一个对象 function Person() {} var o2 = new Person() // 能得到一个对象
- 注意: 首字母不大写,只要和 new 连用,就有创造对象的能力
-
当调用的时候如果不需要传递参数可以不写
()
,建议都写上function Person() {} var o1 = new Person() // 能得到一个空对象 var o2 = new Person // 能得到一个空对象
- 注意: 如果不需要传递参数,那么可以不写 (),如果传递参数就必须写
-
构造函数内部的 this,由于和 new 连用的关系,是指向当前实例对象的
function Person() { console.log(this) } var o1 = new Person() // 本次调用的时候,this => o1 var o2 = new Person() // 本次调用的时候,this => o2
- 注意: 每次 new 的时候,函数内部的 this 都是指向当前这次的实例化对象
-
因为构造函数会自动返回一个对象,所以构造函数内部不要写 return
- 你如果 return 一个基本数据类型,那么写了没有意义
- 如果你 return 一个引用数据类型,那么构造函数本身的意义就没有了
(2)使用构造函数创建一个对象
-
我们在使用构造函数的时候,可以通过一些代码和内容来向当前的对象中添加一些内容
function Person() { this.name = 'Jack' this.age = 18 } var o1 = new Person() var o2 = new Person()
- 我们得到的两个对象里面都有自己的成员 name 和 age
2、组合继承
构造函数继承
function Student(name,age,classroom){
Person.call(this,name,age)
this.classroom = classroom
}
原型继承
Student.prototype = new Person()
构造函数继承+原型继承
//构造函数
function Person(name,age){
this.name = name
this.age = age
this.say()
}
Person.prototype.say = function(){
console.log("hello")
}
//构造函数继承
function Student(name,age,classroom){
this.classroom = classroom //因为函数执行顺序,尽量写在 Person.call(this,name,age)前面
Person.call(this,name,age) //改变Person中的this指向=>Student中的this
}
//原型继承
Student.prototype = new Person()
Student.prototype.say=function(){ //原型覆盖
console.log(this.name,"hello")
console.log(this.name,"你好")
}
Student.prototype.say=function(){ //原型增强,在原来的基础上增强。
Person.prototype.say.call(this) //先执行Person的say(),call改变this指针指向,再加上自己的代码。自动执行函数。
console.log(this.name,"你好")
}
var obj = new Student("kerwin",100,"1班")
3、类的继承
<script>
//类的基础用法
class Person {
constructor(name,age){ //传参格式
this.name=name
this.age=age
// this.say() //调用函数
}
say(){ //定义函数
console.log(this.name,"hello" ,)
console.log("222");
}
}
//继承
class Student extends Person{ //只能继承父类的函数、方法,不会继承形参
constructor(name,age,grade){ //继承父类中的形参
super(name,age) //传参父类
this.grade=grade
this.say()
}
say(){ //增强(覆盖)原有的函数。
// super.say() //在此执行父类中的函数,添加父类中具有的功能
console.log("分数",this.grade);
console.log("111");
}
}
new Student("李四",22,100)
</script>
综合应用案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
width: 400px;
margin: 0 auto;
}
</style>
<script src="./A.js" type="module"></script>
</head>
<body>
<div class="box1">
<h1></h1>
<ul></ul>
</div>
<div class="box2">
<h1></h1>
<ul></ul>
<img src="" alt="">
</div>
<script type="module" >
var data1={
title:"体育",
list:["体育-1","体育—2",'体育-3']
}
var data2 ={
title:"综艺",
list:['综艺-1','综艺-2','综艺-3'],
url:"./图片/aa.jpg"
}
/* //构造函数写法
function Creatobj(select,data){
this.ele = document.querySelector(select) //select类名,直接用作形参来查找dom节点
this.title=data.title
this.list=data.list
this.render()
}
Creatobj.prototype.render=function(){ //对象原型=>在构造函数外定义的一个函数。优点:节省内存空间
var oh1 = this.ele.querySelector("h1") //this.ele=>此时被查找div的dom节点
var oul = this.ele.querySelector("ul")
oh1.innerHTML = this.title
oul.innerHTML = this.list.map(function(item){
return `<li>${item}</li>`
}).join("")
} */
/*类 写法 */
class Creatobj{
constructor(select,data){
this.ele = document.querySelector(select)
this.title=data.title
this.list=data.list
// this.render() //由于运行机制,尽量不要在此运行函数,在实例化后再调用此函数。如果在子类中没有覆盖此函数的话,到此会执行父类的render函数。
}
render(){
var oh1 = this.ele.querySelector("h1")
var oul = this.ele.querySelector("ul")
oh1.innerHTML = this.title
oul.innerHTML = this.list.map(function(item){
return `<li>${item}</li>`
}).join("")
}
}
/* // es5-构造函数继承
function Creatimg(select,data){
this.url=data.url
Creatobj.call(this,select,data) //继承Creatobj的形参,this改变指针方向=>Creatimg的形参,并且自动执行函数
// this.render()
}
Creatimg.prototype.render=function(){
Creatobj.prototype.render.call(this)
//在Creatobj的render()原有的基础上增加功能。.call改变指针指向,并运行函数。
var img = this.ele.querySelector("img")
img.src=this.url
} */
//es6-类的继承
class Creatimg extends Creatobj{ //Creatimg子类,Creatobj父类
constructor(select,data){
super(select,data) //继承父类中的形参,并执行父类
this.url = data.url
this.render()
}
render(){ //覆盖父类中的render函数。
super.render()
var img = this.ele.querySelector("img")
img.src=this.url
}
}
//调用
new Creatobj(".box1",data1).render() //实例化父类,并执行其中的函数。
new Creatimg(".box2",data2)
</script>
</body>
</html>