一、 例:事件监听封装

jQuery 中的事件监听,完全可以用 addEventListener/attachEvent 模拟,分别对应于现代浏览器和 IE ,可以把两个方法封装一下,但是为了方便,这里把其他事件相关处理,如移除事件监听、阻止默认事件等方法统一写在一个对象中,方便调用,具体代码如下:

// 事件处理对象

var EventUtil = {

 // 添加事件监听
add: function(element, type, callback){ if(element.addEventListener){
element.addEventListener(type, callback, false);
} else if(element.attachEvent){
element.attachEvent('on' + type, callback);
} else {
element['on' + type] = callback;
}
}, // 移除事件监听
remove: function(element, type, callback){ if(element.removeEventListener){
element.removeEventListener(type, callback, false);
} else if(element.detachEvent){
element.detachEvent('on' + type, callback);
} else {
element['on' + type] = null;
} }, // 跨浏览器获取 event 对象
getEvent: function(event){ return event ? event : window.event;
}, // 跨浏览器获取 target 属性
getTarget: function(event){ return event.target || event.srcElement;
}, // 阻止事件的默认行为
preventDefault: function(event){ if(event.preventDefault){
event.preventDefault();
} else {
event.returnValue = false;
}
}, // 阻止事件流或使用 cancelBubble
stopPropagation: function(){ if(event.stopPropagation){
event.stopPropagation();
} else {
event.cancelBubble = true;
}
} }; // 使用例子
var at = document.getElementbyId('atemp');
EventUtil.add(at, 'click', function(){ console.log('被点击了'); event = EventUtil.getEvent(event); // 跨浏览器获取 event 对象
EventUtil.preventDefault(event); // 阻止默认事件
});

一、生成实例对象的原始模式

假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性。

  var Cat = {

    name : '',

    color : ''

  }

现在,我们需要根据这个原型对象的规格(schema),生成两个实例对象。

  var cat1 = {}; // 创建一个空对象

    cat1.name = "大毛"; // 按照原型对象的属性赋值

    cat1.color = "黄色";

  var cat2 = {};

    cat2.name = "二毛";

    cat2.color = "黑色";

好了,这就是最简单的封装了,把两个属性封装在一个对象里面。但是,这样的写法有两个缺点,一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。

二、 原始模式的改进

我们可以写一个函数,解决代码重复的问题。

  function Cat(name,color) {

    return {

      name:name,

      color:color

    }

  }

然后生成实例对象,就等于是在调用函数:

  var cat1 = Cat("大毛","黄色");

  var cat2 = Cat("二毛","黑色");

这种方法的问题依然是,cat1cat2之间没有内在的联系,不能反映出它们是同一个原型对象的实例。

三、 构造函数模式

为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。

所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

比如,猫的原型对象现在可以这样写,

  function Cat(name,color){

    this.name=name;

    this.color=color;

  }

我们现在就可以生成实例对象了。

  var cat1 = new Cat("大毛","黄色");

  var cat2 = new Cat("二毛","黑色");

  alert(cat1.name); // 大毛

  alert(cat1.color); // 黄色

这时cat1cat2会自动含有一个constructor属性,指向它们的构造函数。

  alert(cat1.constructor == Cat); //true

  alert(cat2.constructor == Cat); //true

Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系。

  alert(cat1 instanceof Cat); //true

  alert(cat2 instanceof Cat); //true

四、构造函数模式的问题

构造函数方法很好用,但是存在一个浪费内存的问题。

请看,我们现在为Cat对象添加一个不变的属性type(种类),再添加一个方法eat(吃)。那么,原型对象Cat就变成了下面这样:

  function Cat(name,color){

    this.name = name;

    this.color = color;

    this.type = "猫科动物";

    this.eat = function(){alert("吃老鼠");};

  }

还是采用同样的方法,生成实例:

  var cat1 = new Cat("大毛","黄色");

  var cat2 = new Cat ("二毛","黑色");

  alert(cat1.type); // 猫科动物

  cat1.eat(); // 吃老鼠

表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。那就是对于每一个实例对象,type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率。

  alert(cat1.eat == cat2.eat); //false

能不能让type属性和eat()方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?回答是可以的。

五、 Prototype模式

Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。

  function Cat(name,color){

    this.name = name;

    this.color = color;

  }

  Cat.prototype.type = "猫科动物";

  Cat.prototype.eat = function(){alert("吃老鼠")};

然后,生成实例。

  var cat1 = new Cat("大毛","黄色");

  var cat2 = new Cat("二毛","黑色");

  alert(cat1.type); // 猫科动物

  cat1.eat(); // 吃老鼠

这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。

  alert(cat1.eat == cat2.eat); //true

六、 Prototype模式的验证方法

为了配合prototype属性,Javascript定义了一些辅助方法,帮助我们使用它。,

6.1 isPrototypeOf()

这个方法用来判断,某个proptotype对象和某个实例之间的关系。

  alert(Cat.prototype.isPrototypeOf(cat1)); //true

  alert(Cat.prototype.isPrototypeOf(cat2)); //true

6.2 hasOwnProperty()

每个实例对象都有一个hasOwnProperty()方法,用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。

  alert(cat1.hasOwnProperty("name")); // true

  alert(cat1.hasOwnProperty("type")); // false

6.3 in运算符

in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。

  alert("name" in cat1); // true

  alert("type" in cat1); // true

in运算符还可以用来遍历某个对象的所有属性。

  for(var prop in cat1) { alert("cat1["+prop+"]="+cat1[prop]); }

javascript之封装(引用网络)的更多相关文章

  1. Openlayer3之C++接口在javaScript的封装使用

    0.写在前面: 1)涉及的关键词定义: 传入:JavaScript向CAPI传值 传出:CAPI向JavaScript传值 2)关于类和结构体的封装,需要严格执行内存对齐,以防止读取越界,但是避免不了 ...

  2. 基于AFNetworking封装的网络请求工具类【原创】

    今天给大家共享一个我自己封装的网络请求类,希望能帮助到大家. 前提,导入AFNetworking框架, 关于修改AFN源码:通常序列化时做对text/plan等的支持时,可以一劳永逸的修改源代码,在a ...

  3. JavaScript的封装和继承

    提到JavaScript"面向对象编程",主要就是封装和继承,这里主要依据阮一峰及其他博客的系列文章做个总结. 继承机制的设计思想 所有实例对象需要共享的属性和方法,都放在这个对象 ...

  4. JavaScript 模块封装

    JavaScript 模块封装 前言介绍 在最早的时候JavaScript这门语言其实是并没有模块这一概念,但是随着时间的推移与技术的发展将一些复用性较强的代码封装成模块变成了必要的趋势. 在这篇文章 ...

  5. 2016/11/17 周四 <javascript的封装简单示例>

    这是一个简单的javascript代码封装的示例以及封装后的调用方法: var ticker={ n:0, add:function() { this.n++; }, show:function() ...

  6. SharePoint 2010自定义母版页小技巧——JavaScript和CSS引用

    通常在我们的项目中,都会涉及到母版页的定制.并且必不可少的,需要配合以一套自己的JavaScript框架和CSS样式.你有没有遇到过这样的情况呢,在开发环境和UAT时都还算顺利,但是当最终部署到生产服 ...

  7. PHP javascript 值互相引用(不用刷新页面)

    PHP javascript 值互相引用的问题   昨天通过EMAIL给一些公司投了简历,希望他们能给我一份工作,今天其中一家公司的人给我打电话,大意是要我做一点东西(与AJAX有关) 给他们看,我听 ...

  8. 封装获取网络信息Linux—API类

    封装获取网络信息Linux—API类 封装好的库: #ifndef NETINFORMATION_H #define NETINFORMATION_H #include <netdb.h> ...

  9. JavaScript语法细节——引用与复制

    原文:JavaScript语法细节--引用与复制 我们都知道,JS中变量的赋值有两种方式,最近在折腾自己写的标签栏插件,碰到了很多平时没注意的问题.正好,那边处理清楚了,稍微整理一下关于引用与复制相关 ...

  10. 第一百三十五节,JavaScript,封装库--拖拽

    JavaScript,封装库--拖拽 封装库新增1个拖拽方法 /** tuo_zhuai()方法,将一个弹窗元素实现拖拽功能 * 注意:一般需要在css文件将元素里的某一个区块光标设置成提示可以拖拽, ...

随机推荐

  1. opencv学习之路(8)、基本图像运算——加减与或

    一.图像加法 #include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespa ...

  2. extjs的使用笔记2

    系统的大部分资源(安装程序的除bin, lib, conf等之外的东西)都是放在 /usr/share/目录中的 在用户自己定义的, 一些关于系统资源的东西, 则放在目录 ~/.local/share ...

  3. js归并排序

    js归并排序 function mergeSort (arr){ if (arr.length < 2){ //控制语句,结束递归 return arr; } var middle = Math ...

  4. Linux command: grep

    How to use grep to match multiple strings in the same line? grep 'string1\|string2' filename grep -E ...

  5. P3980 [NOI2008]志愿者招募

    思路 巧妙的建图 因为每个志愿者有工作的时段,所以考虑让一个志愿者的流量能够从S流到T产生贡献 所以每个i向i+1连INF-a[x]的边(类似于k可重区间集),每个si向ti连边cap=INF,cos ...

  6. Java中substring函数的简单应用

    1.删掉一个字符串中的某个字符 /* * 使用Java 中的 substring()函数删掉字符串中的某个字符 * deleteAssignChar函数的参数说明: * str:被操作的字符串 * o ...

  7. [bug] - 关于poi导入excel时间格式会减少8小时的问题.

    这个bug发生在使用poi组件导入导出excel时,(这里是导入) 首先在excel中的格式设定是 yyyy-mm-dd hh:mm:ss 通过配套使用ExcelUtil中 getCellValue( ...

  8. C语言: 从 CodeBlocks 到 Microsoft Visual Studio 2017

    开学到现在寒假,学习了一个学期的C语言,同时也已然用了大半年的 CodeBlocks 来写 C/C++ 程序.CodeBlocks 是写 C/C++ 语言的程序最轻量的IDE(集成开发环境),在 C ...

  9. python学习打卡 day12 生成器

    本节主要内容 : 生成器 生成器函数 各种推导式 生成器表达式 一.生成器 什么是生成器.生成器的本质就是迭代器. 在python中有三种方式来获取生成器: 1.通过生成器函数 2.通过各种推导式来实 ...

  10. 如何判断一个js对象是否是Array

    经常遇到一个问题,判断某个对象是否为数组类型,在Js中检测对象类型的常见方式有以下: typeof操作符 对于Function.String.Number.Undefined等几种类型的对象来说,几乎 ...