原型对象补充
原型模式
定义:每个函数在创建时,都会创建一个prototype属性,这个属性是一个对象,也就是构造函数创建对象的原型,在构造函数中赋给对象实例的值,可以直接赋给他们的原型
<script>
function Person(){
Person.prototype.name='jack'
Person.prototype.age=20
Person.prototype.say=function(){
console.log(this.name,'说话');
}
}
let person1=new Person()
person1.say()
//结果jack说话
</script>
共享实例对象
<script>
function Person(name,age){
this.name=name,
this.age=age
}
// Person.prototype.say=function(){
// console.log(this.name,'说话');
// }
// let p1=new Person('jack',20)
// p1.say()
//注释内容也可用下面代码替代
Person.prototype={
say:function(){
console.log(this.name,'说话');
}
}
let p1=new Person('jack',20)
p1.say()
</script>
理解原型
只要创建函数,就有一个prototype属性指向原型对象,原型对象也有一个constructor指向函数,也就是Person.prototype.constructor===Person
<script>
function Person(){
Person.prototype.name='jack'
Person.prototype.age=20
Person.prototype.say=function(){
console.log(this.name,'说话');
}
}
console.log(typeof Person.prototype);
//结果Object
//也就是Person原型是个对象
console.log(Person.prototype);
//结果{constructor:f}
//原型对象有个方法指向构造函数,这个函数里就包含了Person里的属性和方法
console.log(Person.prototype.__proto__===Object.prototype);
//结果true
//也就是任何函数的原型对象的原型与Object的原型是指向一致
console.log(Person.prototype.__proto__.__proto__);
//结果null
//也就是Object的原型的原型为空,也就是到Object原型就截止了
let person1=new Person()
let person2=new Person()
console.log(person1.__proto__);
//结果{name: 'jack', age: 20, say: ƒ, constructor: ƒ}
//也就是实例对象通过 __proto__到达构造函数的原型
console.log(person1.__proto__===person2.__proto__);
//结果true
//也就是实例对象的原型指向一致
</script>
设置和获取原型对象
- getPrototypeOf()获取原型对象
<script>
function Person(){
Person.prototype.name='jack'
Person.prototype.age=20
Person.prototype.say=function(){
console.log(this.name,'说话');
}
}
let person1=new Person()
let person2=new Person()
console.log(Object.getPrototypeOf(person1));
//结果{name: 'jack', age: 20, say: ƒ, constructor: ƒ}
console.log(Object.getPrototypeOf(person1.name));
结果jack
</script>
- setPrototypeOf()设置原型对象
<script>
let person={
name:'jack'
}
let age={
age:20
}
Object.setPrototypeOf(person,age)
console.log(person.age);
//结果20
</script>
- 通过setPrototypeOf()设置原型对象修改继承关系会造成性能下降,所以一般用Object.create()设置原型对象
<script>
let age={
age:20
}
let person=Object.create(age)
person.name='jack'
console.log(person.age);
//结果20
</script>
原型链
定义:2个或2个以上原型,通过隐藏原型__proto__属性连接起来,形成的链式解构连接起来
原型链作用:属性方法继承
在多个原型对象的属性和方法,实例对象通过原型链进行访问或者实例对象沿着原型链方向查找属性和方法
在真正的面向对象语言中,在定义对象之前,先创建对象类型
class Person{
constructor(name,age){
this.name=name
this.age=age
}
say(){
console.log(this.name,'说话')
}
}
let P1=new Person('jack',18)
//结果jack说话
注:这只是构造函数语法糖,在JS编译器里还是构造函数
选项卡(先创建对象类型,再定义类型)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
.tab{
width: 600px;
height: 600px;
margin: 0 auto;
}
ul{
width: 600px;
height: 50px;
}
ul li{
width: 198px;
height: 50px;
background-color: pink;
float: left;
list-style: none;
border: 1px solid orange;
text-align: center;
line-height: 50px;
}
.active{
background-color: orange;
}
.box{
width: 600px;
height: 550px;
background-color: skyblue;
text-align: center;
line-height: 550px;
}
</style>
</head>
<body>
<div class="tab" id="tab1">
<ul>
<li>选项1</li>
<li>选项2</li>
<li>选项3</li>
</ul>
<div class="box">选项1</div>
</div>
<script>
class Tab{
constructor(id){
this.root=document.querySelector(id)
this.uls=this.root.querySelectorAll('ul>li')
this.box=this.root.querySelector('.box')
}
onClear(){
this.uls.forEach(item => {
item.classList.remove('active')
});
}
onTab(){
let _this=this
for(let i=0;i<this.uls.length;i++){
this.uls[i].οnclick=function(){
_this.onClear()
_this.uls[i].classList.add('active')
let content=this.innerHTML
_this.box.innerHTML=content
}
}
}
}
let t1=new Tab('#tab1')
t1.onTab()
</script>
</body>
</html>