对象(类)的封装方式(面向对象的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: 面向过程与面向对 ...
随机推荐
- JavaScript的因为所以
各位看官,楼主开始说过写几篇博客,这是这个系列的最后一集.吾以为:了解JavaScript的身世之谜,掌握其近乎心想事成的变量系统,了解其解析运行的偷梁换柱之法,熟悉布大师迂回曲折的OOP实现.那你离 ...
- putty 中文乱码解决方法
解决putty.exe 中文乱码的问题 export NLS_LANG="AMERICAN_AMERICA.ZHS16GBK"
- Android Studio 错误 Duplicate files copied in APK META-INF/LICENSE.txt
1 .Duplicate files copied in APK META-INF/LICENSE.txt android { packagingOptions { exclude 'META-I ...
- Bit Twiddling Hacks
http://graphics.stanford.edu/~seander/bithacks.html Bit Twiddling Hacks By Sean Eron Andersonseander ...
- SCVMM之Windows Server2012 R2新功能
在Windows Server 2012 R2中可以通过使用共享的虚拟硬盘VHDX文件的方法来模拟IP SAN,来为虚拟机创建群集提供共享存储.这样为虚拟机创建群集时就不用再像以前一样通过使用软件模拟 ...
- Sqlite表的结构修改
Sqlite删除列方法 http://blog.csdn.net/aben_2005/article/details/6563538 SQLite3 table 结构修改 http://blog.cs ...
- Html游戏开发-画图
1. 画矩形和写字 var canvas = document.getElementById('canvas'), context = canvas.getContext('2d'); context ...
- Codeforces Round #306 (Div. 2) A. Two Substrings 水题
A. Two Substrings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/550/pro ...
- uoj #5. 【NOI2014】动物园 kmp
#5. [NOI2014]动物园 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/5 Description 近日 ...
- 模拟log4j获取日志对象调用所在的类名、方法名及行号
当我们在记录日志时,每个类中会定义一个日志对象,然后利用这个对象去写日志,那么我们在处理日志时,如何能才能记录日志对象所在的类.方法和行号呢?log4j中已经实现了该功能,那么它是怎么实现的呢? 其实 ...