面向对象三大特征
-
封装
:把代码放入对象的方法中
-
继承
:子对象拥父对象的所有属性和方法(js的重点)
-
多态
:一个对象在不同情况下的多种状态
继承
-
混入式继承
: 遍历父对象成员, 添加给子元素
特点: 单个对象继承
-
替换原型继承
: 父对象作为子对象构造函数的原型
特点: 多个对象继承,但是会覆盖原来的默认原型
-
混合式继承
: 混入式+替换原型 遍历父元素成员, 添加给子对象构造函数原型
特点: 多个对象继承,不会覆盖原来的默认原型
混入式继承
<script>
// 父对象
let father = {
house: {
address: '光谷天地',
price: 10000000
},
car: {
brand: '宝马',
price: 1000000
}
}
// 子对象
let son = {
name: '张三',
age: 18
}
// 混入式继承: 遍历父对象成员,添加给子元素
// 特点: 单个对象继承
for (let key in father) {
son[key] = father[key]
}
console.log(son)
</script>
替换原型继承
<script>
// 父对象
let father = {
house: {
address: '光谷天地',
price: 10000000
},
car: {
brand: '宝马',
price: 1000000
}
}
// 子对象构造函数
function son(name, age) {
this.name = name
this.age = age
}
// 子对象的默认原型
son.prototype.hobby = function () {
console.log('打麻将')
}
// 替换原型继承: 父对象作为子对象构造函数的原型
// 特点: 用于多对象继承,但是会覆盖原来的原型
son.prototype = father
let son1 = new son('张三', 20)
let son2 = new son('李四', 30)
console.log(son1, son2)
混合式继承
<script>
// 父对象
let father = {
house: {
address: '光谷天地',
price: 10000000
},
car: {
brand: '宝马',
price: 1000000
}
}
// 子对象构造函数
function son(name, age) {
this.name = name
this.age = age
}
// 子对象的默认原型
son.prototype.hobby = function () {
console.log('打麻将')
}
// 混入式继承: 混入式+替换原型 遍历父元素成员,添加给子对象构造函数原型
// 特点: 多对象继承,不会覆盖原来的默认原型
for (let key in father) {
son.prototype[key] = father[key]
}
let son1 = new son('张三', 20)
let son2 = new son('李四', 30)
console.log(son1, son2)
</script>
原型链
-
原型链:每一个对象都有原型,原型本身又是对象,所以原型又有原型,以此类推形成一个链式结构,称为原型链
-
对象访问原型链中成员的规则:
就近原则
当访问一个对象的成员变量时,会首先访问它自身的成员变量,如果有则访问。没有则在原型中寻找,能找到就访问,不能找到则继续往原型的原型中寻找,以此类推,如果找到原型链的顶端还是找不到,则程序报错: xxx is not a function
-
原型链的作用:
继承
js用"原型链"实现面向对象继承
几乎所有的框架底层都是用原型链实现继承
面对对象补充:
静态成员与实例成员
-
静态成员 : 属于函数对象的成员
-
实例成员: 属于实例化对象的成员
<script>
//构造函数
function Person(name,age){
this.name = name
this.age = age
}
Person.aaa = '啊啊啊'
console.log(Person.aaa)//静态成员
//实例化对象
let p1 = new Person('张三',20)
console.log(p1.name)//实例成员
console.log(p1.age)//实例成员
</script>
instanceof运算符
-
instanceof关键字(运算符): 检测构造函数的原型prototype在不在这个对象的原型链上
-
作用:限制函数的参数数据类型
-
语法:实例对象 instanceof 构造函数
<script>
//数组实例对象
// arr->Array.prototype->Object.prototype->null
let arr = [10,20,30]
console.log( arr instanceof Array )//true
console.log( arr instanceof Object )//true
console.log( arr instanceof String )//false
//报错: 参数不是节点
//instanceof关键字一般用在函数中,用于限制参数的数据类型
//例如 appendChild()参数只能是node节点,如果你传了其他类型就会报错。底层就会用到instanceof来检测参数数据类型
let h1 = document.createElement('h1')
h1.innerText = '我是h1标签'
document.body.appendChild(h1)
</script>