正如爱因斯坦所说的:javascript
若是你不能把它解释给一个六岁的小孩,说明你对它还不够了解。java
我曾尝试向一个27岁的朋友解释js
闭包而且彻底失败了。你会如何向一个有概念(例如,函数,变量等)的人解释,来弥补闭包知识,但不理解闭包自己?jquery
不管什么时候你看到function
关键字在另外一个函数内部,那么内部函数将可访问外部函数的变量。json
function foo(x) { var tmp = 3; function bar(y) { alert(x + y + (++tmp)); // will alert 16 } bar(10); } foo(2);
这将老是弹出16
,由于函数bar
能够访问变量 x
,它是做为foo
参数定义的,也能够访问变量tmp
。api
这就是一个闭包。函数没有任何返回的时候就被称为闭包。简单地访问即时词法做用域(immediate lexical scope
)外的变量建立了一个闭包。浏览器
function foo(x) { var tmp = 3; return function (y) { alert(x + y + (++tmp)); // will also alert 16 } } var bar = foo(2); // bar is now a closure. bar(10);
上面的函数也会弹出16,由于 bar
仍然能够指向 x
和 tmp
,即便它再也不直接范围内。安全
然而,由于 tmp
仍然在bar
的闭包内部闲逛,它也正在增长。每次你调用bar
的时候它会被增长。
最简单的闭包的例子是这个:session
var a = 10; var b = 6; function test() { console.log(a); // will output 10 console.log(b); // will output 6 } test();
当一个js
函数被调用的时候,一个新的执行上下文环境就被建立了。函数参数和父对象一块儿,这个执行上下文也接收全部的外部声明的变量(在上面的例子,'a'
和 'b'
都是)闭包
建立多个闭包函数是可能的,或者经过返回他们的列表,或者经过设置他们的全局变量。全部这些将指向同上面的x
和tmp
,他们不会拷贝他们自己。ecmascript
这里的数字 x
是字面量的数字。和js
其余字面量同样,当foo
被调用,数字 x
就被复制到 foo
内做为它的 参数 x
另外一方面,当处理对象的时候,js
总会使用引用。若是说,你用一个Object
来调用foo
,闭包将会返回最先引用的Object
function foo(x) { var tmp = 3; return function (y) { alert(x + y + tmp); x.memb = x.memb ? x.memb + 1 : 1; alert(x.memb); } } var age = 2; var bar = foo(age); // bar is now a closure referencing age. bar(10);
果真,每次调用bar(10)
都将增长x.memb
。这也许不是所预期的,x
仅仅是指向一样的对象 做为age
变量!通过几回调用bar
以后,age.memb
将是2!这是与HTML
对象引用的内存泄漏的基础
jQuery
是没有必要的,而且window.location.replace(...)
将最佳模拟HTTP
重定向。
这比使用window.location.href =
要好,由于replace()
并不把起始页放入会话历史(session history
)里,这意味着用户不会陷入永无休止的后退按钮的窘境。若是你想要模拟人点击一个连接,请使用location.href
。若是要模拟一个HTTP
重定向,使用location.replace
。
例如:
// 相似HTTP重定向的行为 window.location.replace("http://stackoverflow.com"); // 相似点击一个连接的行为 window.location.href = "http://stackoverflow.com";
在jQuery中,能够切换元素的可见性,使用方法.hide(), .show() 或者.toggle(). 使用jQuery,你如何测试一个元素是可见的仍是隐藏的?
由于这个问题是指一种单一的元素,因此该代码可能更适合:
// 检查display:[none|block], 忽略 visible:[true|false] $(element).is(":visible");
你可使用hidden
选择器:
// 匹配的是隐藏的全部元素 $('element:hidden')
和visible
选择器:
// 匹配全部可见的元素 $('element:visible')
最近,我运行个人一些JavaScript
代码经过Crockford
的JSLint
的,它给了如下错误:
Problem at line 1 character 1: Missing "use strict" statement.
作了一些搜索,我意识到是有些人添加了“use strict”
到他们的JavaScript
代码中。有一次,我添加了该声明,错误就中止出现了。不幸的是,谷歌并无透露太多这字符串声明的历史的背后。固然,它必定和javascript
如何被浏览器解析有关系,但我不知道效果会怎样。
那么,什么是"use strict"
;全部和它仍然相关联的涵义是什么?
当前任何浏览器是否对"use strict"
作出反应;该字符串或是在未来作使用?
这篇文章也许对你有帮助:
John Resig - ECMAScript 5 Strict Mode, JSON, and More
引用一些有趣的部分:
严格模式是`ECMAScript 5`中的一项新特征,容许你把一段程序或功能放置在"strict"工做环境中。这种严格上下文环境防止某些行为被采起并引起更多的异常。
而且:
严格的模式有助于几个方面: 它捕获了一些常见的编码错误,抛出异常。 它阻止,或抛出错误,当相对“不安全”的行为被采用(例如获取全局对象)。 它禁用那些混淆的或者考虑不周的特征
另外请注意,你能够在整个文件中申请严格模式
...或者你能够仅在特定的函数中使用它(仍然是引用John Resig
的文章):
// 非严格的代码... (function(){ "use strict"; // 严格定义你的库... })(); // 非严格的代码
若是你有混合使用新旧代码,它可能会有所帮助;-)
因此,我认为这是一个有点像"use strict"
,你能够在Perl
(所以得名?)中使用:它经过检测更多可能致使破坏的事情来帮助你少犯错误。
在javascript
中,我如何检测一个字符串包含另外一个子字符串。一般我会想到String.contains()
方法,但彷佛没有一个。
indexOf
返回一个字符串在其余字符串中的位置。若是没找到,它会返回-1
var s = "foo"; alert(s.indexOf("oo") > -1);
是否有一个经过jQuery
无插件查询字符串值的方式(或者没有)。
若是是,怎么作?若是不是,是否有一款能够这么作的插件?
你不须要经过jQuery
就能够达到那个目的。你能够仅仅使用纯javascript
:
function getParameterByName(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); }
用法:
var prodId = getParameterByName('prodId');
我最近开始维护别人的JavaScript
代码。我修复bug
,增长功能,也试图整理代码并使其更加一致。
以前的开发人员使用两种函数声明方式,我没法弄清是否这背后有或没有解决的缘由。
两种方法是:
var functionOne = function() { // Some code }; function functionTwo() { // Some code }
使用这两种不一样方法的缘由是什么,以及各自的利弊是什么?
所不一样的是functionOne
被定义在运行时,而functionTwo
被限定在分析时的脚本块。例如:
<script> // Error functionOne(); var functionOne = function() { }; </script> <script> // No error functionTwo(); function functionTwo() { } </script>
这也意味着在严格的模式下,你不能有条件地使用第二语法定义函数:
<script> "use strict"; if (test) { // Error function functionThree() { doSomething(); } } </script>
若是没有"use strict"
这将不会致使一个错误 而且 functionThree
将被定义无关test
的值。
我用JSLint
来检查javascript
,当我在作相似比较idSele_UNVEHtype.value.length == 0
的时候,接着它返回许多建议用===
(三个等号)来替换==
(两个等号)
用 ===
来取代==
是否有性能优点?
当有许多比较操做符存在的时候,任何性能的改进都将很受欢迎。
若是没有类型转换发生,性能会超过==
?
恒等式(===)操做符
参考文献:JavaScript教程:比较运算符
==
操做符在作任意按需类型转换后将比较相等性,而===
操做符并不会, ===
运算符将不作转换,因此若是两值不同类型===
将返回false
。这种状况下,===
将更快,并可能比==
返回不一样的结果。在全部其余状况下的性能都是同样的。
引用 Douglas Crockford
的JavaScript: The Good Parts
javascript拥有两套等性运算符: `===`和`!==`,和他们邪恶的双胞胎 `==`和`!=`。好的那一个会按你所指望的方式工做。若是两个操做数是相同的类型,具备相同的值,那么`===`产生`true`,`!==`产生`false`。当操做数具备相同类型时,邪恶双胞胎作正确的事,可是若是他们是不一样类型,它们试图强制值。他们这么作的规格是复杂难记的,这里有一些有趣的例子: '' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' \t\r\n ' == 0 // true
个人建议是不要使用邪恶的双胞胎。相反,老是用===
和!==
。全部的比较只是产生虚假的= = =运算符。用===
操做符的全部的比较仅显示false
更新:
var a = [1,2,3]; var b = [1,2,3]; var c = { x: 1, y: 2 }; var d = { x: 1, y: 2 }; var e = "text"; var f = "te" + "xt"; a == b // false a === b // false c == d // false c === d // false e == f // true e === f // true
特殊状况下,当你比较字面量和对象的时候,考虑到它的toString
或者valueOf
方法。例如,考虑比较由字符串构造函数建立的字符串对象和字符串字面量
"abc" == new String("abc") // true "abc" === new String("abc") // false
这里的==
操做符正在检查这两个对象的值并返回true
,可是鉴于它们不是相同类型而且===
返回false
。哪个是正确的?这实际上取决于你想要比较什么。个人建议是彻底绕过这个问题,只是不使用字符串构造函数建立字符串对象。
原文连接:http://stackoverflow.com/ques...
克隆一个js
对象的最有效的方法是什么?我已经见过obj = eval(uneval(o));
被使用,可是目前仅有Firefox支持。在 Mootools 1.2
,我已经作了相似obj = JSON.decode(JSON.encode(o));
的事情,可是存在效率问题
我也见过递归复制功能的各类缺陷。我很惊讶,没有规范的解决方案存在。
注:这是另外一个答复,没有对这个问题做出恰当的回应。若是你但愿快速复制一个对象请参考:[Corban's advice in his
answer][4] 他对这个问题的回答。
我想指出,jQuery
中的.clone()
方法只克隆DOM
元素。为了克隆JavaScript
对象,你须要这么作:
// 浅拷贝 var newObject = jQuery.extend({}, oldObject); // 深拷贝 var newObject = jQuery.extend(true, {}, oldObject);
更多信息请参考:http://api.jquery.com/jQuery....
我还想指出,深拷贝其实比上面所示聪明得多 - 它是可以避免不少陷阱(例如,想深扩展DOM
元素)。它被频繁地用于jQuery
的核心而且在插件里也有重大的做用
彷佛没有一个内置的方法,你能够尝试:
function clone(obj) { if(obj == null || typeof(obj) != 'object') return obj; var temp = obj.constructor(); // changed for(var key in obj) { if(obj.hasOwnProperty(key)) { temp[key] = clone(obj[key]); } } return temp; }
我是这么建立一个对象的:
var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
以new myJSONObject
结束的移除属性regex
的最好方法是什么?
var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI"};
delete myJSONObject.regex; // or, delete myJSONObject['regex']; // or, var prop = "regex"; delete myJSONObject[prop];
var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; delete myJSONObject.regex; alert ( myJSONObject.regex); // alerts: undefined
这种方法在火狐和IE
下起做用,我我的认为在其余浏览器也起做用