JS面向对象(一)——构造函数的封装

基本概念

对象:对象就是一个整体,对外提供一个整体。

面向对象:使用对象时,只关注对象提供的功能,不关注其内部的细节。

三个特点(类C++):封装、继承、多态

一些概念区别

1、方法与函数

方法:obj.fn = function(){}

函数:function fn(){}

其中函数 function fn(){} 相当于 window.fn = function(){}

2、类与对象

类:不具备实际的功能,只能用来构造对象

对象:真正有功能的东西,被类给构造出来的

封装构造函数(工厂模式)

以person为对象举例 (有两个属性 name sex)

 1     <script>
 2         function CreatePerson(name , sex){
 3             var obj = new Object();
 4 
 5             //添加属性
 6             obj.name = name;
 7             obj.sex = sex;
 8 
 9             //添加方法
10             obj.showName = function () {
11                 alert(this.name);
12             };
13             obj.showSex = function () {
14                 alert(this.sex);
15             };
16             return obj;
17         }
18 
19         var p1 = CreatePerson('leo' , 'male');
20         var p2 = CreatePerson('shawn' , 'male');
21         p1.showName();
22         p1.showSex();
23 
24         alert(p1.showName == p2.showName);
25     </script>
View Code

以这样的方式(其实就是创建一个函数,然后实例对象利用函数传参来实现,这样做的话实例之间是没有什么内在联系的)来构造对象会有两个问题:

1、没有用到new方法

2、每个被创建的对象都有一套自己的方法(例如上述p1.showName()、p2.showName()),而这些方法的实现是一模一样的,这样就造成了资源的极度浪费

解决方案

针对第一个问题,做出的改进如下

 1         function CreatePerson(name , sex){
 2 
 3             //相当于这边有
 4             // var this = new Object();
 5             //添加属性
 6             this.name = name;
 7             this.sex = sex;
 8 
 9             //添加方法
10             this.showName = function () {
11                 alert(this.name);
12             };
13             this.showSex = function () {
14                 alert(this.sex);
15             };
16             //这边有return this;
17         }
View Code

这个时候生成的实例对象会自动包含一个constructor属性,指向它们的构造函数

当然还可以使用instanceof来验证实例对象是否属于原型对象

 

针对第二个问题,我们可以使用prototype(原型),Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。这很像CSS中的class,可以给一堆对象加上相同的属性或方法。主要是用来添加一些系统不支持的方法或函数

 1    <script>
 2         function CreatePerson(name , sex){
 3             //添加属性
 4             this.name = name;
 5             this.sex = sex;
 6         }
 7         //添加共用方法
 8         CreatePerson.prototype.showName = function () {
 9             alert(this.name);
10         };
11         CreatePerson.prototype.showSex = function () {
12             alert(this.sex);
13         };
14 
15         var p1 = new CreatePerson('leo' , 'male');
16         var p2 = new CreatePerson('shawn' , 'male');
17         p1.showName();
18         p1.showSex();
19 
20         alert(p1.showName == p2.showName);
21     </script>
View Code

这个时候我们会发现最后的输出是true,这时候用的都是同一个内存地址,指向了prototype对象,内存的使用效率就变高。

 

最后关于一个优先级的问题

 

 1     <script>
 2         Array.prototype.a = 12;  //给Array类添加公共属性a = 12;
 3         var arr = [1,2,3];
 4         alert(arr.a);  //12
 5 
 6         arr.a = 5;   //给由Array类所创造的对象arr添加重名属性a
 7         alert(arr.a);  // 5
 8 
 9         delete  arr.a;  //删除arr对象的a属性
10         alert(arr.a);  //12
11     </script>
View Code

 

我们会发现这和CSS中内部样式和行间样式很相像,prototype添加的属性相当于一个内部样式 ,而对象的重名属性相当于行间样式 , 所以重名时对象的属性优先级肯定是高于prototype所添加的属性的。

 

转载于:https://www.cnblogs.com/JDDDD/p/5392231.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值