JS闭包研究、自造困扰与解答
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
//------------------------------------------------------------------
var intCount = 0;
function Add() {
return intCount++;
}
//------------------------------------------------------------------
var AddPkgErr = function () {
var intCount = 0;
//var intCountErr = 0;
AddPkgErr.prototype.Add = function () {
//return intCount++;
return intCount++;
//return intCountErr++;
}
}
//------------------------------------------------------------------
var AddPkgOK = function () {
//定義包的變量
AddPkgOK.prototype.intCount = 0;
//AddPkgOK.prototype.intCountOK = 0;
//定義包的方法
AddPkgOK.prototype.Add = function () {
return AddPkgOK.prototype.intCount++;
//return AddPkgOK.prototype.intCountOK++;
}
}
var AddPkg3 = function () {
//定義包的變量
this.intCount = 0;
//定義包的方法
this.Add = function () {
return this.intCount++;
}
}
//====================================================================
function test1()
{
WriteLog("=====================================");
WriteLog("非閉包,每次累加:" + Add());
} function test21() {
WriteLog("=====================================");
var objAddPkg = new AddPkgErr();
WriteLog("閉包單組21,每次都是新的:" + objAddPkg.Add());
}
function test22() {
WriteLog("=====================================");
var objAddPkg = new AddPkgOK();
WriteLog("閉包單組22,每次都是新的:" + objAddPkg.Add());
}
function test3() {
WriteLog("=====================================");
WriteLog("閉包多組,每組都是新的並且組與組之間互不影響(錯誤結果)");
var objAddPkg1 = new AddPkgErr();
WriteLog("第一組,第一次:" + objAddPkg1.Add());
WriteLog("第一組,第二次:" + objAddPkg1.Add());
WriteLog("第一組,第三次:" + objAddPkg1.Add());
WriteLog("=====================================");
var objAddPkg2 = new AddPkgErr();
WriteLog("第二組,第一次:" + objAddPkg2.Add());
WriteLog("第二組,第二次:" + objAddPkg2.Add());
WriteLog("第二組,第三次:" + objAddPkg2.Add());
WriteLog("=====================================");
WriteLog("第一組,第四次:" + objAddPkg1.Add());
WriteLog("第二組,第四次:" + objAddPkg2.Add());
}
function test4() {
WriteLog("=====================================");
WriteLog("閉包多組,每組都是新的並且組與組之間互不影響(預期結果)");
var objAddPkg1 = new AddPkgOK();
WriteLog("第一組,第一次:" + objAddPkg1.Add());
WriteLog("第一組,第二次:" + objAddPkg1.Add());
WriteLog("=====================================");
var objAddPkg2 = new AddPkgOK();
WriteLog("第二組,第一次:" + objAddPkg2.Add());
WriteLog("第二組,第二次:" + objAddPkg2.Add());
WriteLog("=====================================");
WriteLog("第一組,第三次:" + objAddPkg1.Add());
WriteLog("第二組,第三次:" + objAddPkg2.Add());
} function test5() {
WriteLog("=====================================");
WriteLog("閉包多組,每組都是新的並且組與組之間互不影響(預期結果)");
var objAddPkg1 = new AddPkg3();
WriteLog("第一組,第一次:" + objAddPkg1.Add());
WriteLog("第一組,第二次:" + objAddPkg1.Add());
WriteLog("=====================================");
var objAddPkg2 = new AddPkg3();
WriteLog("第二組,第一次:" + objAddPkg2.Add());
WriteLog("第二組,第二次:" + objAddPkg2.Add());
WriteLog("=====================================");
WriteLog("第一組,第三次:" + objAddPkg1.Add());
WriteLog("第二組,第三次:" + objAddPkg2.Add());
}
function WriteLog(sMsg) {
txtMsg.innerHTML = txtMsg.innerHTML + sMsg + "\n";
}
</script> </head>
<body>
<input id="btnTest1" type="button" onclick="test1();" value="非閉包" />
<input id="btnTest2" type="button" onclick="test21();" value="閉包單組" />
<input id="btnTest3" type="button" onclick="test22();" value="閉包單組" />
<input id="btnTest4" type="button" onclick="test3();" value="閉包多組多次(錯誤結果)" />
<input id="btnTest5" type="button" onclick="test4();" value="閉包多組多次(預期結果)" />
<input id="btnTest6" type="button" onclick="test5();" value="閉包多組多次(正确)" />
<input id="btnClear" type="button" onclick="txtMsg.innerHTML = '';" value="清空" />
<br />
<textarea id="txtMsg" rows="2" cols="20" style="width:100%; height:600px;"></textarea>
</body>
</html>
上面的代码关于“閉包多組多次(錯誤結果)”和“閉包多組多次(預期結果)”,红色字体结果都不是我预期的,还请教一下大家,感恩! 预期的结果应该是:
=====================================
閉包多組,每組都是新的並且組與組之間互不影響(預期結果)
第一組,第一次:0
第一組,第二次:1
=====================================
第二組,第一次:0
第二組,第二次:1
=====================================
第一組,第三次:2
第二組,第三次:3--->2(期望是2)
=====================================
閉包多組,每組都是新的並且組與組之間互不影響(錯誤結果)
第一組,第一次:0
第一組,第二次:1
第一組,第三次:2
=====================================
第二組,第一次:0
第二組,第二次:1
第二組,第三次:2
=====================================
第一組,第四次:3
第二組,第四次:4--->3(期望是3)
-----------------------------------------------------------
又仔细看了一边,真发现自己太粗心。
直接this就搞定了,唉。
人家明明写的:这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。
仔细思考应该可以认为:AddPkgErr中var intCount = 0;和AddPkgOK中AddPkgOK.prototype.intCount = 0;应该效果是一样的。
参考资料:
http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html
JS闭包研究、自造困扰与解答的更多相关文章
- 探讨js闭包
背景:爱就要大胆说出来,对于编程我只想说,喜欢就大胆写出来.喜欢却不行动那就意味着失败.所以,对于在研究编程的猿们,我对同伴们说,大胆的学,大胆的写.呵呵,说这些其实无非是给我自己点动力,写下去的勇气 ...
- 浅谈js闭包(closure)
相信很多从事js开发的朋友都或多或少了解一些有关js闭包(closure)的知识. 本篇文章是从小编个人角度,简单地介绍一下有关js闭包(closure)的相关知识.目的是帮助一些对js开发经验不是很 ...
- js闭包的作用域以及闭包案列的介绍:
转载▼ 标签: it js闭包的作用域以及闭包案列的介绍: 首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- Js闭包常见三种用法
Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...
- js闭包之初步理解( JavaScript closure)
闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解. 要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域, ...
- (原创)JS闭包看代码理解
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...
- js闭包理解
js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...
- js闭包理解实例小结
Js闭包 闭包前要了解的知识 1. 函数作用域 (1).Js语言特殊之处在于函数内部可以直接读取全局变量 <script type="text/javascript"> ...
随机推荐
- 虚拟化之vmware-vsphere概念,原理,功能
080-login-back.vmx .encoding = "UTF-8"config.version = "8"virtualHW.version = &q ...
- noip2011普及组——统计单词数
统计单词数 时间限制:1 s 内存限制:128MB [问题描述]一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实 ...
- 【转】.NET 安装和部署(Installer) 如何卸载上一个版本
前言 当使用.NET“安装项目”打包的安装文件,再次安装的时候会弹出如下提示,这个时候会让我们很郁闷,怎样才能自动卸载上一个安装的版本呢?方法很简单,只需简单的两个操作步骤即可解决. 操作步骤 主要由 ...
- FileMode文件模式
一.FileMode.Append Append追加: 如果文件存在,则打开文件,把指针指到文件的末尾:如果不存在,则新建文件 二.FileMode.Create Create:新建 如果文件存在,则 ...
- Linux下 RabbitMQ的安装与配置
以下教程摘录自互联网并做了适当修改,测试的rabbitmq 版本为:rabbitmq-server-generic-unix-3.5.6 各版本之间会有差异!!! 一 Erlang安装 Rabbit ...
- HBase(八): 表结构设计优化
在 HBase(六): HBase体系结构剖析(上) 介绍过,Hbase创建表时,只需指定表名和至少一个列族,基于HBase表结构的设计优化主要是基于列族级别的属性配置,如下图: 目录: BLOOMF ...
- C# Tips: 将 VS2012 / VS2013 的.sln文件、project文件转换成 VS2010格式
原来有一些VS2013的工程文件(.sln..csproj),使用.Net 4.0.现需要将它们转换成VS2010格式. 经实验,办法如下: (1) 在Solution文件(.sln)中: 把文件头部 ...
- Neutron分析(7)—— neutron-l3-agent HA solutions
1. keepalived vrrp/conntrackd High availability features will be implemented as extensions or driver ...
- 常用JS
window.opener.location.reload(); 刷新上一个页面 window.opener=null;window.open('','_self');window.close(); ...
- grep,sed,cut,awk,join个性特点
grep 从数据文件中查询/提取出含有特定关键字的行. sed 主要用于对数据文件中特定字符串的替换处理. cut 按照指定的分隔符(-d)剪下选定的列(-f num)或者字符(-c)的内容. awk ...