上一个月一直忙于项目,没写过笔记,今天稍微空下来了一点

前几天在写项目的时候关于怎么去封装每一个组件的时候思考到几种方式,这里总结一下:

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基本知识)的更多相关文章

  1. Learn day6 模块pickle\json\random\os\zipfile\面对对象(类的封装 操作 __init__)

    1.模块 1.1 pickle模块 # ### pickle 序列化模块 import pickle """ 序列化: 把不能够直接存储的数据变得可存储 反序列化: 把数 ...

  2. js if for 详解 获取元素方式 及一些js 基础知识

    ##获取元素的新方法## --document.querySelector('Css Selector{css选择器}') 接收一个css选择器(通配,群组,类,包含,id....等) 若这个选择器对 ...

  3. linux下线程的两种封装方式

    在网络编程的时候往往需要对Linux下原生的pthread库中的函数进行封装,使其使用起来更加方便,封装方法一般有两种:面向对象和基于对象,下面将分别介绍这两种方式,最后统一分析这两种方式的优缺点: ...

  4. js面向对象(对象/类/工厂模式/构造函数/公有和原型)

    https://www.cnblogs.com/sandraryan/ 什么是对象 js中一切都是对象(有行为和特征).js允许自定义对象,也提供了内建对象(string date math等) 对象 ...

  5. JS类的封装及实现代码

    js并不是一种面向对向的语言, 没有提供对类的支持, 因此我们不能像在传统的语言里那样 用class来定义类, 但我们可以利用js的闭包封装机制来实现js类, 我们来封装一个简的Shape类. 1. ...

  6. JavaScript学习12 JS中定义对象的几种方式【转】

    avaScript学习12 JS中定义对象的几种方式 转自:  http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象. ...

  7. JS类继承常用方式发展史

    JS类继承常用方式发展史 涉及知识点 构造函数方式继承 1-继承单个对象 1.1 多步走初始版 1.2 多步走优化版 1.3 Object.create()方式 2-继承多个对象 2.1 遍历 Obj ...

  8. python中的面向对象学习以及类的封装(这篇文章初学者一定要好好看)

    这篇文章对于初学者可以很有效的理解面对过程.面对对象 一.首先介绍一下面向过程和面向对象的比较: 面向过程 VS 面向对象 编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何 ...

  9. 09_Java面向对象_第9天(类、封装)_讲义

    今日内容介绍 1.面向对象思想 2.类与对象的关系 3.局部变量和成员变量的关系 4.封装思想 5.private,this关键字 6.随机点名器 01面向对象和面向过程的思想 A: 面向过程与面向对 ...

随机推荐

  1. Windows x86 x64使用SetThreadContext注入shellcode的方式加载DLL

    一.前言 注入DLL的方式有很多,在R3就有远程线程CreateRemoteThread.SetWindowsHookEx.QueueUserApc.SetThreadContext 在R0可以使用a ...

  2. jquery checkbox选中状态

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. ECharts地图中tooltip提示框通过formatter分别显示多个数值

    我原来的CSDN博客上写过这篇文章:http://blog.csdn.net/giscript/article/details/52162165 但是现在发现了代码中存在一个bug,在此更正. 按照原 ...

  4. tab栏切换的特殊效果(类似网易的登陆栏效果)

    代码显示效果如上图所示: 需求说明: 在实际需求中,会遇到这样的情况:不仅是要展示选项卡的内容,而且还有可能在选项卡中需求顾客填写相关内容,而这些内容是顾客如果想了解更深层次的,就会继续填写右边的内容 ...

  5. 汉字简体繁体转换----Javascript

    最近看到有个简体--繁体字互相转换的程序,是用JS实现的,感觉很好玩,所以拿来研究研究.先看看界面如下: 汉字简体繁体转换 // 0&&parent.frames.length) { ...

  6. C++经典面试题

    1.int a=5,则 ++(a++)的值是() A.5      B.   6          C.7       D.逻辑错误 a++返回的是一个暂时变量,这里是右值,不能再前面++了 2.以下 ...

  7. Could not load the assembly 'App_Web_cwclgcuu'. Make sure that it is compiled before accessing the page.

    将网站迁移到windows server 2012 R2(64 bit), IIS 6.2(build 9200)上,爆出这个错误. 解决:右键相应的application pool,选择“Set A ...

  8. Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树/半回文串

    E. Ann and Half-Palindrome Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contes ...

  9. bzoj 1041: [HAOI2008]圆上的整点 数学

    1041: [HAOI2008]圆上的整点 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

  10. WinForm特效:拦截窗体上各个部位的点击

    windows窗体的标题栏无法直接通过一些默认的事件来控制,需要了解和WM_NCHITTEST相关的windows消息. 以下示例演示了最简单的效果片断: 他会把客户区和标题栏的效果互换,比如无法按住 ...