对象(类)的封装方式(面向对象的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: 面向过程与面向对 ...
随机推荐
- effective c++ (一)
条款01:把C++看作一个语言联邦 C++是一种多重范型编程语言,一个同时支持过程(procedural),面向对象(object-oriented),函数形式(functional),泛型形式(ge ...
- QA技能必备
一 常用Linux命令 二 自动化工具
- Jmeter_初步认识随笔
1. 简介 Apache JMeter是100%纯java桌面应用程序,被设计用来测试客户端/服务器结构的软件(例如web应用程序).它可以用来测试包括基于静态和动态资源程序的性能,例如静态文件,Ja ...
- MFC中 Invalidate() , InvalidateRect() , UpdateWindow(), Redrawwindow() 区别
1. void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口 ...
- props 和 state的区别
作者:孙志勇 微博 日期:2016年11月29日 一.时效性 所有信息都具有时效性.文章的价值,往往跟时间有很大关联.特别是技术类文章,请注意本文创建时间,如果本文过于久远,请读者酌情考量,莫要浪费时 ...
- nodejs以及npm的安装
参考资料:http://xiaoyaojones.blog.163.com/blog/static/28370125201351501113581/ 上面的仁兄说的比较清楚,基本解决了安装中遇到的问题 ...
- Eclipse使用jre的原理与配置
近期要配置Eclipse环境,Mark当中的一些方法. 下载Eclipse SDK之后我们就要关联JRE,由于Eclipse启动须要JRE. Eclipse启动时寻找JRE的顺序: 1.假设eclip ...
- Java 多线程编程两个简单的样例
/** * @author gao */ package gao.org; public class RunnableDemo implements Runnable{ @Override publi ...
- curl命令具体解释
对于windows用户假设用Cygwin模拟unix环境的话,里面没有带curl命令,要自己装,所以建议用Gow来模拟,它已经自带了curl工具,安装后直接在cmd环境中用curl命令就可,由于路径已 ...
- iOS开发——网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据
网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一 ...