编程思想
面向过程
分析出解决问题所需要的不招,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。
性能好但不灵活,复用性低
面向对象
把事务分解成一个个对象,然后由对象之间分工与合作。
灵活复用性好但性能不好
面向对象的特性:封装性、继承性、多态性。
构造函数
存在浪费内存的问题。如构造函数中有一个函数,每次创建一个新对象,就会开辟一个新内存,存入该函数,但其实函数代码都是一样的,就造成了内存浪费。
为了解决浪费内存的问题,引入原型。
原型
原型对象
js中,每一个构造函数都有一个prototype属性,指向另一个对象,也称为 原型对象。
我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法。
故:公共的属性写在构造函数身上,公共的方法要写在原型对象身上!
构造函数和原型对象里面的this都指向:实例化后的对象
constructor属性
每个原型对象里面都有一个constructor属性。该属性指向该原型对象的构造函数。
<script>
function Star(name, age) {
this.name = name
this.age = age
}
// Star.prototype.sing = function () {
// console.log('唱歌')
// }
// Star.prototype.dance = function () {
// console.log('跳舞')
// }
console.log(Star.prototype)
//此时可以打印出 原型对象的属性{constructor: ƒ}
Star.prototype = {
// 当有多个对象方法,可以给原型对象采取对象的形式赋值
//但这样 相当于做了赋值操作,就会覆盖构造函数原型对象原来的内容
// 这样修改后的原型对象constructor就不会再指向当前构造函数了
// 所以,要添加一个constructor属性让他指向原来的构造函数
constructor: Star,
sing: function () { console.log('唱歌') },
dance: function () { console.log('跳舞') }
}
console.log(Star.prototype)
//打印结果: {sing: ƒ, dance: ƒ}
//添加constructor:Star,后打印结果为:{constructor: ƒ, sing: ƒ, dance: ƒ}
</script>
对象原型
对象都会有一个属性 __proto__
指向构造函数的prototype原型对象(对象原型指向原型对象),对象能使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__
原型的存在。
[[prototype]]
和 __proto__
意义相同
__proto__
对象原型里面也有一个constructor属性,指向创建该实例对象的构造函数。
原型继承
抽取公共部分,放到一个构造函数中去(父构造函数)。
子类的原型 = new 父类
原型链
只要是对象,就有__proto__
,所以原型对象也有__proto__
原型链:是一种查找规则,先从自身原型对象查找,如果没有就向上一层原型对象查找,直到找不到,为null位置。
instanceof运算符
检测在哪一条原型链上。