StackOverflow上关于JavsScript的热门问答

Q1:javascript的闭包是如何工作的?

正如爱因斯坦所说的:

如果你不能把它解释给一个六岁的小孩,说明你对它还不够了解。

我曾尝试向一个27岁的朋友解释js闭包并且完全失败了。你会如何向一个有概念(例如,函数,变量等)的人解释,来弥补闭包知识,但不理解闭包本身?

Answers:

无论何时你看到function关键字在另一个函数内部,那么内部函数将可访问外部函数的变量。

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。

这就是一个闭包。函数没有任何返回的时候就被称为闭包。简单地访问即时词法作用域(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的时候它会被增加。

最简单的闭包的例子是这个:

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,他们不会拷贝他们本身。

这里的数字 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对象引用的内存泄漏的基础

原文链接:http://stackoverflow.com/questions/111102/how-do-javascript-closures-work

Q2:我如何使用jQuery做一个重定向页面?

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";

原文链接:http://stackoverflow.com/questions/503093/how-can-i-make-a-redirect-page-using-jquery

Q3:测试是否有东西被隐藏

问题描述:

在jQuery中,可以切换元素的可见性,使用方法.hide(), .show() 或者.toggle().

使用jQuery,你如何测试一个元素是可见的还是隐藏的?

Best Answers:

因为这个问题是指一种单一的元素,所以该代码可能更适合:

// 检查display:[none|block], 忽略 visible:[true|false] $(element).is(":visible");

Other Answers:

你可以使用hidden选择器:

// 匹配的是隐藏的所有元素 $('element:hidden')

和visible选择器:

// 匹配所有可见的元素 $('element:visible')

问题链接:http://stackoverflow.com/questions/178325/testing-if-something-is-hidden

Q4:”use strict”在js中的作用是什么,其背后的思考是什么?

问题描述:

最近,我运行我的一些JavaScript代码通过Crockford的JSLint的,它给了以下错误:

Problem at line 1 character 1: Missing "use strict" statement.

做了一些搜索,我意识到是有些人添加了“use strict”到他们的JavaScript代码中。有一次,我添加了该声明,错误就停止出现了。不幸的是,谷歌并没有透露太多这字符串声明的历史的背后。当然,它一定和javascript如何被浏览器解析有关系,但我不知道效果会怎样。

那么,什么是"use strict";所有和它仍然相关联的涵义是什么?

当前任何浏览器是否对"use strict"做出反应;该字符串或是在将来做使用?

Best Answers:

这篇文章也许对你有帮助:

John Resig – ECMAScript 5 Strict Mode, JSON, and More

引用一些有趣的部分:

严格模式是`ECMAScript 5`中的一项新特征,允许你把一段程序或功能放置在"strict"工作环境中。这种严格上下文环境防止某些行为被采取并引发更多的异常。

并且:

严格的模式有助于几个方面:

它捕获了一些常见的编码错误,抛出异常。

它阻止,或抛出错误,当相对“不安全”的行为被采用(例如获取全局对象)。

它禁用那些混淆的或者考虑不周的特征

另外请注意,你可以在整个文件中申请严格模式…或者你可以仅在特定的函数中使用它(仍然是引用John Resig 的文章):

// 非严格的代码... (function(){ "use strict"; // 严格定义你的库... })(); // 非严格的代码

如果你有混合使用新旧代码,它可能会有所帮助;-)

所以,我认为这是一个有点像"use strict",你可以在Perl(因此得名?)中使用:它通过检测更多可能导致破坏的事情来帮助你少犯错误。

原文链接:http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it

Q5:如何检测一个字符串包含另一个子字符串?

问题描述:

在javascript中,我如何检测一个字符串包含另一个子字符串。通常我会想到String.contains()方法,但似乎没有一个。

Best Answers:

indexOf返回一个字符串在其他字符串中的位置。如果没找到,它会返回-1

var s = "foo"; alert(s.indexOf("oo") > -1);

原文地址:http://stackoverflow.com/questions/1789945/how-can-i-check-if-one-string-contains-another-substring

Q6:我如何在JavaScript中获得查询字符串的值?

问题描述:

是否有一个通过jQuery无插件查询字符串值的方式(或者没有)。

如果是,怎么做?如果不是,是否有一款可以这么做的插件?

Best Answers:

你不需要通过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');

问题链接:http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

Q7:var functionName = function() {} vs function functionName() {}

问题描述:

我最近开始维护别人的JavaScript代码。我修复bug,增加功能,也试图整理代码并使其更加一致。

之前的开发人员使用两种函数声明方式,我无法弄清是否这背后有或没有解决的原因。

两种方法是:

var functionOne = function() { // Some code }; function functionTwo() { // Some code }

使用这两种不同方法的原因是什么,以及各自的利弊是什么?

Best Answers:

所不同的是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的值。

原文链接:http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname

Q8:JavaScript 中应该用 “==” 还是 “===”?

问题描述:

我用JSLint来检查javascript,当我在做类似比较idSele_UNVEHtype.value.length == 0的时候,接着它返回许多建议用===(三个等号)来替换==(两个等号)

用 ===来取代==是否有性能优势?

当有许多比较操作符存在的时候,任何性能的改进都将很受欢迎。

如果没有类型转换发生,性能会超过== ?

Best Answers:

恒等式(===)操作符

参考文献: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://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

原文链接:http://stackoverflow.com/questions/359494/does-it-matter-which-equals-operator-vs-i-use-in-javascript-comparisons

Q9:克隆一个对象的最有效的方法是什么?

问题描述

克隆一个js对象的最有效的方法是什么?我已经见过obj = eval(uneval(o));被使用,但是目前仅有Firefox支持。在 Mootools 1.2,我已经做了类似obj = JSON.decode(JSON.encode(o));的事情,但是存在效率问题

我也见过递归复制功能的各种缺陷。我很惊讶,没有规范的解决方案存在。

Best Answers:

注:这是另一个答复,没有对这个问题作出恰当的回应。如果你希望快速复制一个对象请参考:[Corban’s advice in hisanswer][4] 他对这个问题的回答。

我想指出,jQuery中的.clone()方法只克隆DOM元素。为了克隆JavaScript对象,你需要这么做:

// 浅拷贝 var newObject = jQuery.extend({}, oldObject); // 深拷贝 var newObject = jQuery.extend(true, {}, oldObject);

更多信息请参考:http://api.jquery.com/jQuery.extend/

我还想指出,深拷贝其实比上面所示聪明得多 – 它是能够避免很多陷阱(例如,想深扩展DOM元素)。它被频繁地用于jQuery的核心并且在插件里也有重大的作用

Other answers:

似乎没有一个内置的方法,你可以尝试:

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; }

原文链接:http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object/122704#122704

Q10:如何从一个JavaScript对象中删除一个属性

问题描述:

我是这么创建一个对象的:

var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

以new myJSONObject结束的移除属性regex的最好方法是什么?

var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI"};

Best Answers:

delete myJSONObject.regex; // or, delete myJSONObject['regex']; // or, var prop = "regex"; delete myJSONObject[prop];

参考:understanding delete

Other Answers:

var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; delete myJSONObject.regex; alert ( myJSONObject.regex); // alerts: undefined

这种方法在火狐和IE下起作用,我个人认为在其他浏览器也起作用

原文发布于微信公众号 - 交互设计前端开发与后端程序设计(interaction_Designer)

原文发表时间:2016-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java工会

导致程序崩溃的一行代码,你有写过吗?

初学编程时,可能经常遇到一些程序崩溃的现象。一般来说,程序崩溃由于操作不当引起的。但是有时候,因为一个程序员的粗心,正式版本的程序出现崩溃状况这就很不因该了。之...

13520
来自专栏前端黑板报

Sass vs Less

2007年发布,最早的一款CSS预处理器,带来了变量、常量、嵌套、混入、函数、循环等功能, 解决了CSS不可编程的短板。由于浏览器不能直接识别Sass,所以需要...

23890
来自专栏向治洪

ES7、ES8新特性

概述 JavaScript,作为一门处于高速发展期的开发语言,正在变的越来越完善、稳定。我们必须拥抱这些变化,并且我们需要把ES8加入到我们的技术栈中。 E...

1.9K50
来自专栏贾老师の博客

Boost 中的智能指针

10420
来自专栏影子

jQuery中的常用内容总结(三)

转载请注明地址:http://www.cnblogs.com/funnyzpc/p/7571998.html

11110
来自专栏游戏杂谈

全局变量的三种声明方法

显示true FWK未定义,说明隐式声明的全局变量可以被delete,与global对象的parseInt、escape、parseFloat等等类似,可直接被...

13510
来自专栏TungHsu

这或许是对小白最友好的python入门了吧——13,字典初识

前边我们学习了列表、元组等储存元素的方式,今天我们来看一个更为强大的:字典。 像列表用方括号[]、元组用圆括号()一样,字典用花括号{} 先编写一个简单的词典,...

35150
来自专栏GreenLeaves

Vue.js系列之四计算属性和观察者

一、计算属性 1、模版内的表达式非常便利,但是设计它们的初衷是用于简单计算的。在模版中放入太多的逻辑运算会让模版过重且难以维护,例如如下代码: <div id=...

25360
来自专栏TungHsu

这或许是对小白最友好的python入门了吧——2,变量和字符串

长期以来,编程界都认为刚接触一门新语言时,如果首先使用它来编写一个在屏幕上显示消息 “Hello world!” 的程序,将给你带来好运。 因为微信排版编辑问题...

28850
来自专栏影子

jQuery中的常用内容总结(三)

11920

扫码关注云+社区

领取腾讯云代金券