JS的面向对象编程一:封装
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的面向对象编程一:封装的更多相关文章
- Javascript面向对象编程一:基础篇
该随笔分为以下四部分: Javascript面向对象编程一:基础篇 Javascript面向对象编程二:封装 Javascript面向对象编程三:继承 Javascript面向对象编程四:控件 先弄个 ...
- vue.js学习之better-scroll封装的轮播图初始化失败
vue.js学习之better-scroll封装的轮播图初始化失败 问题一:slider组件初始化失败 原因:页面异步获取数据很慢,导致slider初始化之后,数据还未获取到,导致图片还未加载 解决方 ...
- node.js连接数据库基本操作、封装数据库操作,输出到网页
声明:以下代码测试通过,不同于直接的复制粘贴乱七八糟未测试的代码,完全可以用,最后会附上所有的代码和sql文件 首先建立表,建表语句如下: /* SQLyog Ultimate v12.08 (64 ...
- js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用)
js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用) 一.总结 2.匿名函数作为参数传递 二.js进阶ajax函数封装 ajax1.js function ajax(ur ...
- python基础-面向对象编程之封装、访问限制机制和property
面向对象编程之封装 封装 定义:将属性和方法一股脑的封装到对象中,使对象可通过"对象."的方式获取或存储数据. 作用:让对象有了"."的机制,存取数据更加方便 ...
- JS和JQUERY常见函数封装方式
JS中常用的封装函数4种方法: 1. 函数封装法: function box(){ } 2. 封装成对象 : let Cookie = { get(){ }, set(){ } } 3. 封装成构造函 ...
- JS面向对象编程之封装
来源:https://segmentfault.com/a/1190000015843072 我们所熟知的面向对象语言如 C++.Java 都有类的的概念,类是实例的类型模板,比如Student表示学 ...
- js原生Ajax的封装与使用
一.原生Ajax代码的封装如下: (function() { var XHR = { createStandardXHR: function() { return new XMLHttpRequest ...
- js原生Ajax 的封装和原理
原理及概念 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是一种用于创建快速动态网页的技术. 动态网页:是指可以通过服务器语言结合数 ...
随机推荐
- [转载] Java CheckBoxTree
代码基本上是copy的.只是在使用上有一些自己的想法. 先上code吧! 虽然别的地方也有.但是还是转一份给自己. 出处:http://blog.csdn.net/joy_125/article/de ...
- 文件上传大小js判断
function fileChange(target) { var fileSize = 0; if (isIE && !target.files) { var filePath = ...
- Erlang--proplists结构解析
proplists 模块适用数据量较少的场景,处理配置文件和函数选项时常用.proplists对内部数据结构是Key-Value键值对形式,第一个元素做key用来查询和删除,如果一个key有多个值就会 ...
- python中date、datetime、string的相互转换
import datetime import time string转datetime str = '2012-11-19' date_time = datetime.datetime.strptim ...
- C++开始前篇,深入编译链接(3)
一,COMMON块 什么是COMMON块,这是一种机制,早期的Fortran没有动态分配空间的机制,程序员必须事先声明它所需要的临时使用空间的大小.Fortran把这种空间叫做COMMON块,当不同的 ...
- XStream xml 解析框架使用笔记
1. xml的标签可以映射为类.类成员变量 2. 有子标签的标签映射为类,没有子标签的便签映射为类成员变量 3. 类名.类成员变量名如与标签名不一致需要通过注解或代码设置别名 // 类名 @XStre ...
- Oracle 和 SqlServer 的区别
--sql server 与 oracle的区别: --DBMS 数据库管理系统--1.数据类型不同. --sql server 的数据类型:int ,smallint ,char,var ...
- windows系统 SVN出现 can't open file‘\XXX\txn-current-lock’ 拒绝访问 问题处理
问题描述: 在新建的svn目录下,提交文件出现 如图错误提示.
- C++ 系列:内存布局
转载自http://www.cnblogs.com/skynet/archive/2011/03/07/1975479.html 为什么需要知道C/C++的内存布局和在哪可以可以找到想要的数据?知道内 ...
- cmake cannot find package
cmake 找不到package,如 find_package (OpenMesh REQUIRED) 出现错误 在项目的文件夹中找到 FindOpenMesh.cmake 文件,将其所在路径添加到 ...