学习目标
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的 时候再一个一个的依次调用即可。
就是按照我们分析好步骤,按照步骤解决问题
面向对象是把事务分解成一个个对象,然后由对象之间分工与合作。
面向对象就是以对象功能来划分问题,而不是步骤。
面向对象的特性:
封装性
继承性
多态性
⭕️面向过程编程
优点:性能比面向对象高,适合跟硬件联系很紧密的东西。例如单片机采用的面向过程编程。
缺点:没有面向对象以维护,不易复用,不易扩展。
❌面向对象编程
优点:易维护,易复用,由于面向对象由封装,继承,多态的特性。可以设计出低耦合的系统,使系统更加灵活,更加易维护。
缺点:性能比面向过程低。
变量
和函数
组合到一起并通过this实现数据的共享
,所不同的使借助构造函数创建出来的实例对象之间是彼此不影响的。// 构造函数 公共的属性和方法 封装到 Star 构造函数里面了
// 1.公共的属性写到 构造函数里面
function Star(uname, age) {
this.uname = uname
this.age = age
this.sing = function () {
console.log('唱歌')
}
}
const ldh = new Star('刘德华', 55)
const zxy = new Star('张学友', 58)
ldh.sing() //调用
zxy.sing() //调用
前面我们学过的构造函数方法很好用,但是存在浪费内存的问题。每一次创建对象都会生成新的方法。
console.log(ldh === zxy) // false
console.log(ldh.sing === zxy.sing) // true
公共的方法写到原型对象身上,对象实例化不会多次创建原型上函数,节约了内存。
Star.prototype.sing = function () {
console.log('唱歌')
}
目标:能够利用原型对象实现方法共享
共享的
每一个构造函数都有一个prototype 属性
,指向一个对象,所有也称为原型对象。prototype
对象上,这样所有对象的实例化就可以共享这些方法`。Function Star(uname,age)
this,uname=uname
this,age=age
console.log(Star.prototype)//返回一个对象称为原型对象
Star.prototype.sing function (){
console.1og("我会唱歌)
}
const 1dh = new Star('刘德华',18)
const zxy = new Star('张学友',19)
console.1og(ldh.sing == zxy.sing)
//结果是true说明俩函数一样,共享
函数this指向的还是 实例对象 ldh,
每一个原型对象都有一个constructor 属性 (constructor 构造函数
)
使用场景:如果有多个对象的方法,我们可以给原型对象采取对象形式赋值。但是这样会覆盖构造函数原型对象原来的内容。 需要在原型对象种指向创造的constructor: 构造函数名字
function star(name){
this.name=name
}
star.prototype = {
//手动利用construtor 指向 star
construtor : star// 如果不指向 就会默认指向object
console.log(star.prototype.constructor)//指向 object
sing : function()console.log("sing"),
dance : function()console.log("dance")
}
console.log(star.prototype.constructor)//指向原型对象star
思考
构造函数可以创建实例对象,构造函数还有一个原型对象,一些公共的属性或方法放到这个原型对象可以共享属性和方法?
答:对象都会有一个属性_proto_
指向构造函数的 prototype原型对象 ,因为对象有_proto_ 原型的存在。
function Star() {
}
const ldh = new Star()
// 对象原型__proto__ 指向 改构造函数的原型对象
console.log(ldh.__proto__) // object
console.log(ldh.__proto__ === Star.prototype) // true
// 对象原型里面有constructor 指向 构造函数 Star
console.log(ldh.__proto__.constructor === Star) // true
❌注意
- _proto _ 是 JS非标准属性
- [{prototype}] 和 proto 意义相同
- 用来表明当前实例对象指向哪个原型对象prototype
- proto 对象原型里面有一个constructor属性,
指向创建该实例对象的构造函数
通过继承进一步提升代码封装的程度,JavaScript大多是借助原型对象实现继承的特性。
function Man(){
this.head =1;
this.eyes =2;
this.legs =2;
this.say =function (){}
this.eat= function (){}
}
const pink= new Man()
console.log(pink)// Man 对象
✊ 封装–抽取公共部分
//人类
const People ={
head:1,
eyes:2,
legs:2,
say:function (){},
eat:function (){}
}
//男人
function Man(){
}
// 把公共的属性和方法给原型,这样就可以共享
Man.prototype = People // 原型继承
//让原型里面的constructor 从新指回向Man构造函数,因为原型对象会把继承的对象完全覆盖。
Man.prototype.constructor =Man
const pink = new Man()
console.log(pink)
男人和女人都同时继承使用了同一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都影响。
如果男人添加吸烟的方法,女人的对象原型也会添加。
Man.prototype.smoking= function(){}
完善继承写法,即消除原型对象指向同一个固定对象。
构造函数继续抽取,new 出来的对象,结构一样 ,对象不一样,地址不一样。这样就可以使用父类的属性和方法。
function Man(){}
// 父构造函数(父类) 子构造函数(子类)
// 子类的原型 = new 父类
Man.prototype = new Person() //构造函数继续抽取构造原型对象
// 让原型里面的constructor 从新指向找自己的父级
Man.prototype.constructor = Man
Man.prototype.smoking = function(){}
console.log(Man)
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这个关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链。
查找规则
个对象自身
有没有该属性。prototype 原型对象
Object
为止(null)_ proto_ 对象原型
的意义就只在于为对象成员查找机制提供一个方向,或者说一条路线。这章理解面向对象思路,并且掌握函数原型对象,
会用面向对象封装继承特点,实现封装方法的使用。
今日练习题