自定义new对象_学会了面向对象,还怕没有对象?

fe9986af43656e4ce256def54a7a69fc.png
面向对象是一种编程思想,我们通过类(构造函数)和对象实现的面向对象编程,满足下述三个特定:封装、继承和多态。

封装

封装创建对象的函数

封装即把实现一个功能的代码封装到一个函数中,以后实现这个功能,只需要执行该函数即可。实现低耦合,高内聚。

现在我们把属性和方法封装成一个对象:

0ff7e84bc4ea6c08690673b13fbaf982.png

如果我们想创建一个不同性别不同姓名的对象,就需要再写一遍上述代码:

9e52f5587cf5f1a2a98f8464490cbb6a.png

如果我们想要创建多个对象的话,写起来就非常麻烦,所以要去封装创建对象的函数解决代码重复的问题。

ac96647f5e54cd5f2e81e694e0b7cfb1.png

然后生成实例对象,就等于是在调用函数:

789a0d966557a957caf8d965d9043f7d.png

上述过程可以类比为开工厂生产酸奶:第一步:需要原料;第二步:加工酸奶;第三步:出厂售卖;我们通过var声明空对象的这一步就相当于第一步原料,添加属性和函数就相当于第二步加工,通过return返回对象就相当于第三步出厂。这种符合上述1、2、3步骤的函数叫做工厂函数,这种设计函数的思路,叫做工厂设计模式。

通过new调用函数

官方函数创建对象的方法是通过new的方法,当我们不使用new创建对象的时候,函数内部的this会指向窗口。

e8d9ac9dea14fd1ec0f781d033d19639.png

所以当我们在函数内部给this.name赋值为xxxx时,可以通过window.name输出xxxx,因为如果这个函数没有主人的话它的主人就是window对象。

d92b23edb33de5a6a45b23f5ae915870.png

但是如果这个函数通过new运算符去调用,那么这个函数中的this,就会指向新创建的对象。

4249b8c686a960b91a50ac0d24a4a8cc.png

当我们通过new运算符去调用函数的时候,它首部和尾部会自动的生成以下两步:1、原料操作:强制改变this指向this = new Object(); 3、出厂操作:将this返回return this;

a0a1932225a4b7cfa457d0b9f9234710.png

所以现在我们改造一下之前创建的函数,调用的时候全部都通过new去调用,并且将函数中的person改成this。

1142f13736ebdf0be26b964454073397.png

构造函数

我们把这种可以创建对象的函数,叫做构造函数。(功能就是用来构造对象)

e439d07cc59e9b83054ae12ca7ede327.png

为了和别的函数,进行区分,我们把构造函数首字母大写。官方的构造函数:Array、Object、Date。

我们通过typeof可以看到官方通过new创建的Object、Array、Date本质上都是function函数。而且所有被该函数,创建的对象,对象的方法都是一套,arr1.push === arr2.push返回值是true。

7d6466052586f03127eb3a3317d448f4.png

但是通过调用函数生成的对象方法,彼此之间没有联系,不能反映出它们是同一个原型对象的实例。alert(p1.showName === p2.showName);返回值为false。

ba6a9959b850415fbf4a2eca0d25b30c.png

我们声明两个数组

83c52d5ce0a76ba5c02ec8359b3ee95d.png

给数组添加求和的函数

0adc68b33fd794c51ad0270ac17db35f.png

调用arr1.sum可以输出arr1的和为150,但是调用arr2.sum会系统报错,提示arr1.sum不是一个函数。因为arr1和arr2是单独的两个对象,给arr1添加一个方法,arr2并不会拥有这个方法。所以我们之前通过new调用函数生成对象后,他们的方法是相互独立的。

e7dbcce7ccffec6b4da7e0cd6990fab6.png

每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。

原型prototype

prototype对象的引入:所有实例对象需要共享的属性和方法,都放在这个对象中,那些不需要共享的属性和方法,就放在构造函数中。以此来模拟类。

所以想让arr2也拥有求和函数就需要再重新写一个arr2.sum,这样就会造成浪费,我们想让对象共用一个方法,这时候就需要引入原型prototype。在JS中一切皆对象,函数也是对象。 每一个被创建的函数,都有一个官方内置的属性,叫做prototype(原型)对象 ,我们输出一下show.protoype,得到结果[object Object]

af5c7a4f13d21903a43def24fb691ddd.png

所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。

如果,我们想要让该函数创建出来的对象,公用一套函数,那么我们应该将这套函数,添加该函数的prototype原型。 所以我们如果想让两个数组都拥有求和的方法,就需要将这个方法添加在Array的原型上。

24b52a6ac1f111034986fcca374316d2.png

现在arr1和arr2都可以使用这个函数,并且arr1.sum == arr2.sum,他们使用的这个函数都是原型上的同一个方法。

42ff2ae73e4257c31de5a2f08a8cae59.png

我们可以通过混合法,让用户自定义构造函数,封装一个可以创建对象的函数,并且调用的是同一个方法。

00fd0a4a81c2996412af7d076484a4de.png

面向对象编程案例

现在我们要测试100辆不同品牌的汽车,记录他们在道路上行驶的性能指数。

创建一个可以构造各式各样车的构造函数

08b3829f600da6d2da42fa8f2739e157.png

在Car的原型上添加功能:让车跑在路上,计算时速。

1. Car.prototype.run = function(road){2. alert(`一辆${this.type}品牌的${this.name}系列,时速为${this.speed}km/h的车,跑在长度为${road.length}km的${road.name},最终的成绩是${road.length / this.speed}小时`);3. }

创建一个可以构造各式各样马路的构造函数

7a374d925d5e09a2a3205cd27284a52e.png

添加第一个测试用例car1:

1. var kuahaidaqiao = new Road("跨海大桥
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值