对象(类)的封装方式(面向对象的js基本知识)
上一个月一直忙于项目,没写过笔记,今天稍微空下来了一点
前几天在写项目的时候关于怎么去封装每一个组件的时候思考到几种方式,这里总结一下:
1、构造函数方式(类似java写类的方式):把所有的属性和方法全部挂在构造函数内部的this上:
function Textarea(opts) {
this.defaults = {
//...这是一些默认属性
};
this.options = $.extend(true, {}, this.defaults, opts);
this.creatDom = function() {
//...这里面很大一堆代码
};
this.setVal = function() {
//...这是很大一堆代码
};
this.getVal = function() {
//...这是很大一堆代码
};
}
这种方法的优点是代码比较紧凑,比较好理解和代码的管理,但是这样我们每次实例化一个对象的时候都会新开一段内存来存储这个对象(包括方法和属性)
我们改改:
function Textarea(opts) {
this.defaults = {
//...这是一些默认属性
};
this.options = $.extend(true, {}, this.defaults, opts);//这是覆盖以后的属性
this.creatDom = creatDom;
this.setVal = setVal;
this.getVal = getVal;
}
function creatDom() {
//...这是很大一堆代码
}
function setVal() {
//...这是很大一堆代码
}
function getVal() {
//...这是很大一堆代码
}
这样会节约一些内存:但是牺牲了代码的紧凑度;
我们可以知道,每次实例化对象的时候其实三个方法其实是公用的,所以出现了第二种方式去定义对象
2、原型式写法:把属性和方法都挂在到对象的原型上:
function Textarea() {}
Textarea.prototype.defaults = {
//...
};
Textarea.prototype.options = $.extend(true, {}, this.defaults);
Textarea.prototype.creatDom = function() {
//...
};
Textarea.prototype.setVal = function() {
//...
};
Textarea.prototype.getVal = function() {
//...
};
//当然也可以把所有属性和方法放在对象上面然后再挂在prototype上:
function Textarea() {}
Textarea.prototype = {
defaults : {},
options : $.extend(true, {}, this.defaults),
creatDom : function() {},
setVal : function() {},
getVal : function() {}
};
但是这种方法是不可取的,因为这样不能通过参数来构造对象实例(一般每个对象的属性是不相同的);就像fe里面每个人名字不一致,但都能吃能笑能写代码;
举个简单的例子:
function Person(){}
Person.prototype.name = "winter";
Person.prototype.getName = function() { return this.name;}
new Person("summer").getName();//得到的还是winter的大名;
3、构造函数+原型结合的方式:
function Textarea(opts) {
this.defaults = {};
this.option = $.extend(true, {}, this.defaults, opts);
}
Textarea.prototype = {
creatDom : function() {},
setVal : function() {},
getVal : function() {}
};
看看这种方式是不是很完美...
貌似还不完美,这样Textarea.prototype还是在外面,
我们把它也拿到对象里面去:如下
function Textarea(opts) {
this.defaults = {};
this.option = $.extend(true, {}, this.defaults, opts);
Textarea.prototype = {
creatDom : function() {},
setVal : function() {},
getVal : function() {}
};
}
现在看似好了,但是我们每次实例化的时候会发生什么?
都会去执行这对代码:
Textarea.prototype = {
creatDom : function() {},
setVal : function() {},
getVal : function() {}
};
所以我们再做一个步骤,就是让它只执行一次:
function Textarea(opts) {
this.defaults = {};
this.option = $.extend(true, {}, this.defaults, opts);
if(!!this.init){
Textarea.prototype = {
creatDom : function() {},
setVal : function() {},
getVal : function() {}
};
this.init = true;
}
}
OK!一般说来公共属性写在prototype下,需要在实例化的时候改变的属性写在this下
另外我们在实例化对象的时候(new)的时候需要在new的过程中就执行初始化函数:
比如上面的例子我们在var textarea = new Textarea(opts);的时候就想把creatDom函数执行了而不是new Textarea(opts).creatDom();
这时候我们就需要这样:
function Textarea(opts) {
this.defaults = {};
this.option = $.extend(true, {}, this.defaults, opts);
this.creatDom(this.options);
}
Textarea.prototype = {
creatDom : function() {},
setVal : function() {},
getVal : function() {}
};
号外:构造函数下面的this
var die = BlackBerry;
function Phone(){
console.log(this.die);
}
Phone()//BlackBerry
var die = BlackBerry;
function Phone(){
this.die = "Nokia";
console.log(this.die);
}
Phone()//Nokia
构造函数直接调用会把this当作全局window
所以以原型方式写出的对象中没有挂在this下面,直接调用构造函数将不会有这些属性和方法
如果以构造函数的方式生成对象在构造函数直接调用的时候将在window下生成相应的对象和方法
原型下面的this
function Phone() {}
Phone.prototype = {
name : "Nokia",
init : function() {
this.name = "BlackBerry";
}
};
var myPhone = new Phone();
myPhone.init();
console.log(myPhone.name);//BlackBerry
console.log(Phone.prototype.name);//Nokia
init里面的this指的是什么?Phone.prototype?
这里的this指的是调用的实例化对象myPhone;而不是原型对象,看看下面:
console.log(myPhone.hasOwnProperty("name"));//true
这里为true的原因是在调用myPhone.init()是给实例化对象添加乐一个name属性
console.log(myPhone.hasOwnProperty("init"));//false
这里为false很明显,因为start是原型上面的属性而非实例化对象的属性
我差点被骗了:我以为在代码执行的时候myPhone.init();this.name = "BlackBerry";会覆盖Phone.prototype下面的那么属性
对象(类)的封装方式(面向对象的js基本知识)的更多相关文章
- Learn day6 模块pickle\json\random\os\zipfile\面对对象(类的封装 操作 __init__)
1.模块 1.1 pickle模块 # ### pickle 序列化模块 import pickle """ 序列化: 把不能够直接存储的数据变得可存储 反序列化: 把数 ...
- js if for 详解 获取元素方式 及一些js 基础知识
##获取元素的新方法## --document.querySelector('Css Selector{css选择器}') 接收一个css选择器(通配,群组,类,包含,id....等) 若这个选择器对 ...
- linux下线程的两种封装方式
在网络编程的时候往往需要对Linux下原生的pthread库中的函数进行封装,使其使用起来更加方便,封装方法一般有两种:面向对象和基于对象,下面将分别介绍这两种方式,最后统一分析这两种方式的优缺点: ...
- js面向对象(对象/类/工厂模式/构造函数/公有和原型)
https://www.cnblogs.com/sandraryan/ 什么是对象 js中一切都是对象(有行为和特征).js允许自定义对象,也提供了内建对象(string date math等) 对象 ...
- JS类的封装及实现代码
js并不是一种面向对向的语言, 没有提供对类的支持, 因此我们不能像在传统的语言里那样 用class来定义类, 但我们可以利用js的闭包封装机制来实现js类, 我们来封装一个简的Shape类. 1. ...
- JavaScript学习12 JS中定义对象的几种方式【转】
avaScript学习12 JS中定义对象的几种方式 转自: http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象. ...
- JS类继承常用方式发展史
JS类继承常用方式发展史 涉及知识点 构造函数方式继承 1-继承单个对象 1.1 多步走初始版 1.2 多步走优化版 1.3 Object.create()方式 2-继承多个对象 2.1 遍历 Obj ...
- python中的面向对象学习以及类的封装(这篇文章初学者一定要好好看)
这篇文章对于初学者可以很有效的理解面对过程.面对对象 一.首先介绍一下面向过程和面向对象的比较: 面向过程 VS 面向对象 编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何 ...
- 09_Java面向对象_第9天(类、封装)_讲义
今日内容介绍 1.面向对象思想 2.类与对象的关系 3.局部变量和成员变量的关系 4.封装思想 5.private,this关键字 6.随机点名器 01面向对象和面向过程的思想 A: 面向过程与面向对 ...
随机推荐
- Unity3d:加载Format是RGB24位的图片失败(加载图片显示问号)
问题描述:加载图片显示是个红色的问号,调试发现,Texture的Format=RGB24的都加载失败,ARGB32位的都能成功,按照常规,首先去度娘,看是否有人遇到和我同样的问题,结果一无所获.将用N ...
- 全世界最短IE判定if(!+[1,])的解释(转)
全世界最短IE判定if(!+[1,])的解释 虽然从司徒先生的博客上看到 全世界最短的IE判定 很长时间了,却一直对于原理没怎么去细看,今天同事(也是一后台程序员,并非前端)又问到这个问题,于是我 ...
- 常见MFC UI界面库[转]
Xtrme toolkit,BCGControlBar,SkinMagic,AppFace,Skin++,Uskin++,SYGUI,LibUIDK,GuiToolkit,GardenUI等等,除了后 ...
- 详解MyEclipse10 安装Spket 1.6.23(支持Extjs4.1.1及jQuery1.8)
用MyEclipse10安装Spket主要有3种方式:在线下载更新.下载Zip覆盖.下载jar包安装.我用在线安装尝试了N次终于还是失败,只好下载jar包来安装,在失败了M次之后终于安装成功,现在网上 ...
- CMSIS Example - osMessageQ osMessagePut osMessageGet
#include "cmsis_os.h" void Thread0( void * arg); void Thread1( void * arg); osThreadDef( T ...
- rails中的语法
1. erb文件中的语法说明 erb文件中常混合使用Ruby语言和html语言,以下为两种常见的格式 <% 写逻辑脚本(Ruby语法) %> <%= 直接输出变量值或运算结果 %&g ...
- CentOS 6.5 源码安装MySQL5.6
1:下载安装cmake (mysql5.5以后是通过cmake来编译的) #http://download.csdn.net/detail/csxuedn/7976005 #wget http://w ...
- Immutable.js尝试(node.js勿入)
最近做一些复杂html常常需要在页面做一些数据处理,常常在想如果 js有list 这种数据结构多少,今天逛github时 发现有Immutable.js 这个项目https://github.com/ ...
- jQuery 效果 - animate() 方法
http://www.w3school.com.cn/jquery/effect_animate.asp 实例 改变 "div" 元素的高度: $(".btn1" ...
- Java SSH远程执行Shell脚本实现(转)
前言 此程序需要ganymed-ssh2-build210.jar包(下载地址:http://www.ganymed.ethz.ch/ssh2/) 为了调试方便,可以将\ganymed-ssh2-bu ...