今天打算给自己的网站加个地图,原本打算用Goolge Map,但是发现中国大陆的信息太少,碰巧前端时间在网上看到了北京灵图软件技术有限公司也推出了地图服务--51ditu.com。大陆的数据很齐全,虽然部分地区的数据比较久。不过深圳的还算比较新。至少我现在住的星海名城附近的地图还蛮详细准确的。
于是乎,试用了一下搜索接口,copy了文档上的一个例子调试,搜索深圳 星海名城。结果:在地图上出现了很多标准,但是标注的名称都是沁心饼屋。一开始还以为是搜索的结果不对,但是调试了一下发现,是示例代码犯了一个很隐晦的错误。下面会提到这个错误。现在先介绍一下什么是闭包。
一、什么是闭包
Closure (闭包)
A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).
先引用网上的一篇BLOG上的两段话来解释一些闭包,我觉得这个解释还可以。
闭包的解释
- 闭包是ECMAScript(javascript)语言强大的特征之一,如果没有真正的理解它的概念,不可能很好使用它。在一般浏览器环境中,它们很容易被建立,但也会造成比较难理解的代码逻辑。为了避免闭包引起的缺点,利用它所提供的优点,明白它的机制是重要的。javascript语言的闭包很大程度上依靠 scope chains(函数,变量的范围链) 和 javascript对象的灵活的属性机制 实现。
- 闭包简单的解释是,ECMAScript允许inner functions(嵌套函数):函数可以定义在另外一个函数里面(关于嵌套函数可以看看)。这些内部的函数可以访问outer function(父函数)的local变量,参数,其它内部函数。当内部函数被构造,并可以在函数外被获得(函数当成返回值),这个内部函数被在 outer function返回后被执行(在outer函数外执行),那一个闭包形成了。(简单的理解,function被当成数据类型传递或动态执行)。 inner function还有权利访问 那些outer function(父函数)的local变量,参数,其它内部函数。那些outer function(父函数)的local变量,参数,其它内部函数在outer function返回前就有值,并返回的inner function需要改变这些值。
二、51ditu上的示例
js 代码
- var map;
- function showPoint(searchResult)
- {
-
- if(searchResult.count>0)
- {
- map.clearOverLays();
- for(i=0;i
- var poi=searchResult.searchPoints[i];
- var point=new LTPoint(poi.point[0],poi.point[1]);
- map.centerAndZoom(point,0);
- var marker=new LTMarker(point);
- map.addOverLay(marker);
- var name=poi.name;
-
-
- //出错的地方
- LTEvent.bind(marker,"click",marker,function(){this.openInfoWinHtml(name)});
- }
- }
- else
- {
- alert('无结果');
-
- }
- }
问题就出在两句:
js 代码
- var name=poi.name;
-
-
-
- LTEvent.bind(marker,"click",marker,function(){this.openInfoWinHtml(name)});
作者以为 this.openInfoWinHtml(name) 中的name是一个拷贝值,但事实上name是在闭包中声明的,在这里它是一个引用,而不是一个拷贝,所以所有标记的名称都显示为最后一个标记的名称。将上面的例子做一下小修改便可解决这个错误,代码如下:
js 代码
- marker.name=poi.name;
-
-
- LTEvent.bind(marker,"click",marker,function(){this.openInfoWinHtml(this.name)});
这样,marker.name得到的就是每个poi.name的拷贝,而不是最后一个标记的名称的引用。
分享到:
相关推荐
闭包(Closure)是一个可以包含自由变量的代码块,这个自由变量并不是在这个代码块或任何全局上下文中定义的,而是在定义代码块的环境中定义。简单来说,闭包就是在一个函数内部定义另一个函数,内层函数可以引用...
其中闭包 对于那些使用传统静态语言C/C 的程序员来说是一个新的语言特性。本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAscript语言规范来使读者可以更深入的理解闭包。闭包是...
在JavaScript中,每当一个函数被创建时,都会产生一个作用域链。如果该函数内部定义了另一个函数,那么这个内部函数就会捕获外部函数的作用域,形成闭包。即使外部函数执行完毕,内部函数依然可以访问外部函数的变量...
在编程语言理论中,"closure"一词通常指的是“闭包”,它是一个非常重要的概念,尤其是在函数式编程和动态类型语言中。闭包是函数和与其相关的引用环境(即变量的值)的组合,这个组合使得函数能够记住它被定义时的...
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
Javascript中有几个非常...其中闭包 对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性。本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。
Python闭包实例closure.py 简单示例闭包的使用 简单示例闭包的使用
**闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体来说,闭包是由函数及与其相关的引用环境组合而成的一个...
2. 在内存中维持一个变量 3. 通过保护变量的安全实现 JavaScript 私有属性和私有方法 JavaScript 闭包在动画效果中的应用 在网页中实现动画效果主要是利用 JavaScript 脚本语言和 CSS 来改变文档对象的属性,其中...
该控件使用JavaScript闭包原理,编写一个通用的Web图片浏览类,使用CSS控制显示外观,在网页中调用ShowPhotoLib类构造一个图片浏览器的对象,对图片进行控制显示。 4. 实现方法 实现ShowPhotoLib类,需要使用...
闭包是ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下...
标题《JavaScript闭包的理解》涉及的知识点主要围绕JavaScript编程中的一个重要概念——闭包。闭包是一个高级且复杂的话题,它是JavaScript语言的核心特性之一,同时也是一大难点。要想熟练运用JavaScript,掌握闭包...
在JavaScript编程中,“闭包”是一个非常重要的概念,尤其对于希望深入理解和高效使用JavaScript的开发者来说。简单地说,闭包是一种能够记住并访问其创建时周围环境的函数。这种能力使得闭包能够在函数执行完毕后...
本篇文章主要探讨JavaScript函数式编程中的一个重要概念——闭包(closure)。闭包是一种特殊的函数,它能记住其定义时的作用域,即使在函数执行完毕后,仍然可以访问到该作用域内的变量。在JavaScript中,每个函数...
在JavaScript编程中,闭包是一个核心概念,它允许函数记住并访问所在词法作用域,即使当函数在其词法作用域之外执行时。闭包的特性使得它在JavaScript中既神秘又强大。 首先,我们从闭包的定义谈起。在JavaScript中...
在这个例子中,`innerFunction`就是一个闭包,因为它可以访问到`outerFunction`的作用域内的变量`outerVar`,即使`outerFunction`已经执行完毕。`innerFunction`被赋值给了`innerReference`并调用,此时`outerVar`...
通俗地讲,闭包就是在JavaScript中任何函数都可以作为一个闭包,尤其是那些嵌套在其他函数中的函数,它们能够访问外部函数的作用域中的变量。 例如,在以下代码片段中: ```javascript function a() { var i = 0;...
在这个例子中,`inner` 函数形成了一个闭包,因为它保留了对外部函数 `outer` 中变量 `x` 的引用。 #### 二、作用域与作用域链 理解闭包的关键在于理解作用域及其工作原理。 ##### 2.1 执行环境 每个执行代码的上...