JS面向对象编程基础篇(二) 封装操作实例详解


Posted in Javascript onMarch 03, 2020

本文实例讲述了JS面向对象编程封装操作。分享给大家供大家参考,具体如下:

Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。

那么,如果我们要把"属性"(property)和"方法"(method),封装成一个对象,甚至要从原型对象生成一个实例对象,我们应该怎么做呢?

封装

一、 生成实例对象的原始模式

假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性。

var Cat = {



name : '',

               color : ''

      } 

 

现在,我们需要根据这个原型对象的规格(schema),生成两个实例对象。

var cat1 = {}; // 创建一个空对象



cat1.name = "大毛"; // 按照原型对象的属性赋值



cat1.color = "黄色";


var cat2 = {};



cat2.name = "二毛";



cat2.color = "黑色";

好了,这就是最简单的封装了,把两个属性封装在一个对象里面。但是,这样的写法有两个缺点,一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。

二、 原始模式的改进

我们可以写一个函数,解决代码重复的问题。

function Cat(name,color) {



return {




name:name,




color:color



}


}

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

var cat1 = Cat("大毛","黄色");


var cat2 = Cat("二毛","黑色");

这种方法的问题依然是,cat1cat2之间没有内在的联系,不能反映出它们是同一个原型对象的实例。

三、 构造函数模式

为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。

所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

比如,猫的原型对象现在可以这样写,

function Cat(name,color){



this.name=name;



this.color=color;


}

我们现在就可以生成实例对象了。

var cat1 = new Cat("大毛","黄色");


var cat2 = new Cat("二毛","黑色");


console.log(cat1.name); // 大毛


console.log(cat1.color); // 黄色

这时cat1cat2会自动含有一个constructor属性,指向它们的构造函数。

console.log(cat1.constructor == Cat); //true


console.log(cat2.constructor == Cat); //true

Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系。

console.log(cat1 instanceof Cat); //true


console.log(cat2 instanceof Cat); //true

四、构造函数模式的问题

构造函数方法很好用,但是存在一个浪费内存的问题。

请看,我们现在为Cat对象添加一个不变的属性type(种类),再添加一个方法eat(吃)。那么,原型对象Cat就变成了下面这样:

function Cat(name,color){



this.name = name;



this.color = color;



this.type = "猫科动物";



this.eat = function(){console.log("吃老鼠");};


}

还是采用同样的方法,生成实例:

var cat1 = new Cat("大毛","黄色");


var cat2 = new Cat ("二毛","黑色");


console.log(cat1.type); // 猫科动物


cat1.eat(); // 吃老鼠

表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。那就是对于每一个实例对象,type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率。

console.log(cat1.eat == cat2.eat); //false

能不能让type属性和eat()方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?回答是可以的。

五、 Prototype模式

Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。

function Cat(name,color){



this.name = name;



this.color = color;


}


Cat.prototype.type = "猫科动物";


Cat.prototype.eat = function(){console.log("吃老鼠")};

然后,生成实例。

var cat1 = new Cat("大毛","黄色");


var cat2 = new Cat("二毛","黑色");


console.log(cat1.type); // 猫科动物


cat1.eat(); // 吃老鼠

这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。

console.log(cat1.eat == cat2.eat); //true

六、 Prototype模式的验证方法

为了配合prototype属性,Javascript定义了一些辅助方法,帮助我们使用它。,

6.1 isPrototypeOf()

这个方法用来判断,某个proptotype对象和某个实例之间的关系。

console.log(Cat.prototype.isPrototypeOf(cat1)); //true


console.log(Cat.prototype.isPrototypeOf(cat2)); //true

6.2 hasOwnProperty()

每个实例对象都有一个hasOwnProperty()方法,用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。

console.log(cat1.hasOwnProperty("name")); // true


console.log(cat1.hasOwnProperty("type")); // false

6.3 in运算符

in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。

console.log("name" in cat1); // true


console.log("type" in cat1); // true

in运算符还可以用来遍历某个对象的所有属性。

for(var prop in cat1) { console.log("cat1["+prop+"]="+cat1[prop]); }

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
比较简单的一个符合web标准的JS调用flash方法
Nov 29 Javascript
js的image onload事件使用遇到的问题
Jul 15 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
Aug 15 Javascript
javascript中Object使用详解
Jan 26 Javascript
利用原生JS与jQuery实现数字线性变化的动画
Feb 24 Javascript
canvas压缩图片转换成base64格式输出文件流
Mar 09 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
Sep 12 Javascript
在vue中使用echarts图表实例代码详解
Oct 22 Javascript
小程序实现五星点评效果
Nov 03 Javascript
Bootstrap4 gulp 配置详解
Jan 06 Javascript
深入理解JavaScript 箭头函数
May 30 Javascript
vue监听用户输入和点击功能
Sep 27 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
Mar 03 #Javascript
JS面向对象编程基础篇(一) 对象和构造函数实例详解
Mar 03 #Javascript
vue中改变滚动条样式的方法
Mar 03 #Javascript
vue倒计时刷新页面不会从头开始的解决方法
Mar 03 #Javascript
vuex(vue状态管理)的特殊应用案例分享
Mar 03 #Javascript
使用vue打包进行云服务器上传的问题
Mar 02 #Javascript
微信小程序scroll-view的滚动条设置实现
Mar 02 #Javascript
You might like
地球防卫队:陪着奥特曼打小怪兽的人类力量 那些经典队服
2020/03/08 日漫
全国FM电台频率大全 - 14 江西省
2020/03/11 无线电
Email+URL的判断和自动转换函数
2006/10/09 PHP
Php中文件下载功能实现超详细流程分析
2012/06/13 PHP
PHP 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
php使用curl模拟多线程实现批处理功能示例
2019/07/25 PHP
PHP实现文件上传后台处理脚本
2020/03/04 PHP
PHP设计模式入门之迭代器模式原理与实现方法分析
2020/04/26 PHP
js 屏蔽鼠标右键脚本附破解方法
2009/12/03 Javascript
javascript查询字符串参数的方法
2015/01/28 Javascript
JavaScript实现LI列表数据绑定的方法
2015/08/04 Javascript
深入浅析react native es6语法
2015/12/09 Javascript
浅谈JavaScript 中有关时间对象的方法
2016/08/15 Javascript
AngularJs ng-repeat 嵌套如何获取外层$index
2016/09/21 Javascript
JS实现根据用户输入分钟进行倒计时功能
2016/11/14 Javascript
为JQuery EasyUI 表单组件增加焦点切换功能的方法
2017/04/13 jQuery
js模仿微信朋友圈计算时间显示几天/几小时/几分钟/几秒之前
2017/04/27 Javascript
Js实现中国公民身份证号码有效性验证实例代码
2017/05/03 Javascript
nodejs对express中next函数的一些理解
2017/09/08 NodeJs
Vue仿支付宝支付功能
2018/05/25 Javascript
Rollup处理并打包JS文件项目实例代码
2018/05/31 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
详解react native页面间传递数据的几种方式
2018/11/07 Javascript
微信二次分享报错invalid signature问题及解决方法
2019/04/01 Javascript
vue ssr服务端渲染(小白解惑)
2019/11/10 Javascript
[01:20]2018DOTA2亚洲邀请赛总决赛战队Mineski晋级之路
2018/04/07 DOTA
[01:01:52]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第二场 1月9日
2021/03/11 DOTA
30分钟搭建Python的Flask框架并在上面编写第一个应用
2015/03/30 Python
wxPython修改文本框颜色过程解析
2020/02/14 Python
日本民宿预约平台:STAY JAPAN
2017/07/01 全球购物
简历中个人自我评价分享
2014/03/15 职场文书
党员自评材料范文
2014/12/17 职场文书
营销计划书范文
2015/01/17 职场文书
安全第一课观后感
2015/06/18 职场文书
2019个人工作总结
2019/06/21 职场文书