JS的面向对象编程一:封装

时间:2022-09-19 00:11:26

Javascript是一种基于对象的语言,但它又没有class。这在很长的一段时间里,对JS的面向对象编程的概念很模糊,在编程的时候时有用到,但要说个所以然,却说不出来,所以看了些书,又在网上查了些资料,写下些总结。

一、封装

写个对象,将属性(变量),方法写在对象内,这就是封装。如下:我把两个属性封装在函数内。

 var Cat = {
    name : '',
    color : ''
  }

用法:

var cat1 = {}; // 创建一个空对象
cat1.name = "小花"; // 按照原型对象的属性赋值
cat1.color = "黄色";

但这种写法用起来比构造函数模式的麻烦。比较如下:

function cat(name,color){
this.name=name,
this.color=color,
}

用法:

var cat1 = new cat('小花','黄色');

从代码的量上就可以看出,构造的更便捷。

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

而且用同一个构造函数生成的实例,他们之间是有联系的。他们会自动含有一个constructor属性,指向它们的构造函数。代码如下;

console.log(cat1.constructor==cat);  //true
console.log(cat2.constructor==cat); //true
console.log(cat1.constructor==cat2.constructor); //true

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

alert(cat1 instanceof Cat); //true
alert(cat2 instanceof Cat); //true

构造函数虽然好用,但是存在一个浪费内存的问题。如下

function cat(name,color){
this.name=name,
this.color=color
this.type="猫咪";
}

看上去好像没什么问题,但是,每实例化一个对象时,就会生成一个name、color、type,他们都是会占用内存的,而每次生成的type,都是相同的,这就多占用一些内存,缺乏效率。

可喜可贺的是,Javascript提供了一个prototype属性,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

这也就说明,我们可以直接把type写在prototype对象上,如下:

function cat(name,color){
this.name=name,
this.color=color
}
cat.prototype.type="猫咪";

验证下不同实例的type,是否是同一个。如下:

var cat1 = new cat('小花','黄色');
var cat2 = new cat('大花','橘色');
console.log("cat1.type="+cat1.type);
console.log("cat2.type="+cat2.type);
cat1.type="老虎";
console.log("cat1.type="+cat1.type);
console.log("cat2.type="+cat2.type);

但输入的结果却是:

cat1.type=猫咪
cat2.type=猫咪
cat1.type=老虎
cat2.type=猫咪

原因在于cat1这个实例没有type这个属性,这个属性是存在于cat1的原型中,而我们可以通过实例访问原型中的值,却不能通过实例改变原型中的值,如果我们在实例中添加一个属性,而这个属性又刚好于原型中的某个属性同名,那么该属性会屏蔽原型中的属性,最后出现上面那种效果。

下面是一些在网上找的Prototype模式的验证方法:

1、 isPrototypeOf()

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

  alert(Cat.prototype.isPrototypeOf(cat1)); //true

  alert(Cat.prototype.isPrototypeOf(cat2)); //true

2、 hasOwnProperty()

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

  alert(cat1.hasOwnProperty("name")); // true

  alert(cat1.hasOwnProperty("type")); // false

3、 in运算符

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

  alert("name" in cat1); // true

  alert("type" in cat1); // true

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

  for(var prop in cat1) { alert("cat1["+prop+"]="+cat1[prop]); }

JS的面向对象编程一:封装的更多相关文章

  1. Javascript面向对象编程一:基础篇

    该随笔分为以下四部分: Javascript面向对象编程一:基础篇 Javascript面向对象编程二:封装 Javascript面向对象编程三:继承 Javascript面向对象编程四:控件 先弄个 ...

  2. vue.js学习之better-scroll封装的轮播图初始化失败

    vue.js学习之better-scroll封装的轮播图初始化失败 问题一:slider组件初始化失败 原因:页面异步获取数据很慢,导致slider初始化之后,数据还未获取到,导致图片还未加载 解决方 ...

  3. node.js连接数据库基本操作、封装数据库操作,输出到网页

    声明:以下代码测试通过,不同于直接的复制粘贴乱七八糟未测试的代码,完全可以用,最后会附上所有的代码和sql文件 首先建立表,建表语句如下: /* SQLyog Ultimate v12.08 (64 ...

  4. js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用)

    js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用) 一.总结 2.匿名函数作为参数传递 二.js进阶ajax函数封装 ajax1.js function ajax(ur ...

  5. python基础-面向对象编程之封装、访问限制机制和property

    面向对象编程之封装 封装 定义:将属性和方法一股脑的封装到对象中,使对象可通过"对象."的方式获取或存储数据. 作用:让对象有了"."的机制,存取数据更加方便 ...

  6. JS和JQUERY常见函数封装方式

    JS中常用的封装函数4种方法: 1. 函数封装法: function box(){ } 2. 封装成对象 : let Cookie = { get(){ }, set(){ } } 3. 封装成构造函 ...

  7. JS面向对象编程之封装

    来源:https://segmentfault.com/a/1190000015843072 我们所熟知的面向对象语言如 C++.Java 都有类的的概念,类是实例的类型模板,比如Student表示学 ...

  8. js原生Ajax的封装与使用

    一.原生Ajax代码的封装如下: (function() { var XHR = { createStandardXHR: function() { return new XMLHttpRequest ...

  9. js原生Ajax 的封装和原理

    原理及概念 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是一种用于创建快速动态网页的技术. 动态网页:是指可以通过服务器语言结合数 ...

随机推荐

  1. thinkphp-许愿墙-3

    用jquery写异步传递的时候, 首先要判断表单中的输入是否为空: 如果有多个输入项, 应该, 分别的, 一步一步的来判断是否为空, 而不是用 and / or来复合判断! 同时如果为空, 应该将它设 ...

  2. 资源 之 4.3 访问Resource(拾壹)

    4.3.1  ResourceLoader接口 ResourceLoader接口用于返回Resource对象:其实现可以看作是一个生产Resource的工厂类. public interface Re ...

  3. Balloon Comes!

    Problem Description The contest starts now! How excited it is to see balloons floating around. You, ...

  4. delete删除多表

    1.DELETE a.*, aa.* FROM student a, person aa WHERE a.id = aa.city_id AND a.name = '' 2.DELETE a.*, a ...

  5. 蓝桥杯 六角形中填置1~12个数字 dfs

    如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不要填写多余的内容. ...

  6. unity3d在Android端读取修改Json数据

    首先我们需要下载一个文件 LitJson.dll(下载链接 ps: 是用自己的百度云盘下载的如果链接过时,请留言或自行下载, 密码: 5foa) 另外,由于我们要发布到安卓手机上,所以需要配置Jar和 ...

  7. Rails在MacOS上搭建Heroku部署环境

    heroku只是用postgresql,而不能兼容sqlite数据库.所以很重要的一步就是在部署实际产品的时候将数据库类型修改为postgresql,否则你将无法push到heroku上去. hero ...

  8. 关于MongoDB 固定集合(capped collection)的知识梳理

    一 . 什么是固定集合 MongoDB中有一种特殊类型的集合,值得我们特别留意,那就是固定集合(capped collection). 固定集合可以声明collection的容量大小,其行为类似于循环 ...

  9. STM32时钟

    https://blog.csdn.net/qq_29350001/article/details/81409693 这是个大佬讲的 F429有5个时钟源,HSI,HSE,LSI,LSE;PLL; 对 ...

  10. git 入门教程之协同开发

    前面我们已经介绍过远程仓库的相关概念,不过那时并没有深入探讨,只是讲解了如何创建远程仓库以及推送最新工作成果到远程仓库,实际上远程仓库对于团队协同开发很重要,不仅仅是团队协同开发的基础,也是代码备份的 ...