看到这样一个问题:为什么直接在控制台运行{} + []和用console.log({} + [])输出,两者结果不一样?

于是乎打开chrome的控制台运行了一下:

为什么结果会这样呢?不得已学习一下JS中的{}吧

复合语句

 if() {
//...
}else {
//...
}
for() {
//...
}
while() {
//...
}
with(obj) {
//...
}

声明对象直接量

 var obj = {
name: 'Marco',
age: 22,
sex: male
};

声明函数或函数直接量

 function fn1() {
//...
}
var fn2 = function() {
//...
}

没有块级作用域

 for( var i = 0; i < 10; i++) {
doSomething(i);
} alert(i); //

javascript只有函数作用域,以下做法会声明全局变量:

  1. 直接为window添加属性或者赋值  //window.a = 1;
  2. 在function内不使用var声明变量而直接使用
  3. 在function外使用声明变量(无论是否适用var声明)
 function(num1 , num2) {
var sum = num1 + num2;
return sum;
} var result = add(10,20); //
alert(sum); //错误 function(num1 , num2) {
sum = num1 + num2;
return sum;
} var result = add(10,20); //
alert(sum); //

建议在初始化变量之前一定要先声明,这样可以避免不声明而直接初始化变量造成的错误。

当在某个环境中使用一个标识符时,必须先通过搜索来确定该标识符代表什么。搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。若在该环境中找到了该标识符,则搜索停止,变量就绪。若在该局部环境没有找到该变量,则继续沿作用域链向上搜索,一直追溯到全局环境的变量对象。若在全局环境中没有找到该标识符,则说明该变量尚未声明。

 var num = 1;

 function getNum() {
var num = 10;
return num;
} alert(getNum()); //

变量查询是有代价的。很明显,访问局部变量要比访问全局变量更快,因为不用向上搜索作用域链。来看看jquery这么做的:

(function(window, undefined) {
var jQuery = function() {}
// ...
window.jQuery = window.$ = jQuery;
})(window);

这样写的优势:

1、window和undefined都是为了减少变量查找所经过的scope作用域。当window通过传递给闭包内部之后,在闭包内部使用它的时候,可以把它当成一个局部变量,显然比原先在window scope下查找的时候要快一些。(原来的window处于作用域链的最顶端,查找速度慢)

2、在jquery压缩版本jquery.min.js中可以将局部变量window替换成单个字母,减小文件大小,提高加载速度

3、undefined也是JavaScript中的全局属性。将undefined作为参数传递给闭包,因为没给它传递值,它的值就是undefined,这样闭包内部在使用它的时候就可以把它当做局部变量使用,从而提高查找速度。undefined并不是JavaScript的保留字或者关键字。

4、undefined在某些低版本的浏览器(例如IE8、IE7)中值是可以被修改的(在ECMAScript3中,undefined是可读/写的变量,可以给它赋任意值,这个错误在ECMAScript5中做了修正),将undefined作为参数并且不给它传值可以防止因undefined的值被修改而产生的错误。

结构化异常处理的语法符号 

 try {
//...
}catch( ex ){
//...
}finally{
//...
}

语句优先

当{}既可以被理解为复合语句块也可以被理解为对象直接量或函数声明的时候,JavaScript将会将其理解成为复合语句块

 {a:10}  //返回1,而不是对象   : 为标签

 var x = { a:10 } // {a:10}作为右值出现,不能是语句块,只能理解为对象直接量

至此,{}的基本知识就说完了。那么最开始的问题也很好解释了:

{}+[] :根据语句优先原则  {}被理解为复合语句块,因此相当于 {}; +[]   。[]为空,结果为0

console.log({}+[]) : js把()中的语句当做一个表达式,因此{}不能被理解为语句块,而被理解为"[object Object]" + "",console.log("[object Object]"+"")打印结果为[object Object]。

其实 console.log({}+[])和[]+{}的结果相同,原理相同,{}作为右值出现被理解为对象直接量

{}+[] 和[]+{}结果不相同,是不是很神奇。

来来来,做几个练习题压压惊:

 {a: 1} + 2     //
2 + {a: 1} // 2[object Object]
+ {a: 1} // NaN
{foo:[1,2,3]}[0]; // [0]

以上

{}+[]与console.log({}+[])结果不同?从JavaScript的大括号谈起的更多相关文章

  1. JavaScript调试技巧之console.log()详解

    JavaScript调试技巧之console.log()详解 对于JavaScript程序的调试,相比于alert(),使用console.log()是一种更好的方式,原因在于:alert()函数会阻 ...

  2. javascript的console.log用法

    f1.html代码 <iframe id="frame2" name="frame1" src="ww.html"></i ...

  3. Javascript的console.log()用法

    Firebug & Chrome Console 控制台的一些其他功能console.log(object[, object, ...])使用频率最高的一条语句:向控制台输出一条消息.支持 C ...

  4. javascript 中的console.log和弹出窗口alert

    主要是方便你调式javascript用的.你可以看到你在页面中输出的内容. 相比alert他的优点是: 他能看到结构话的东西,如果是alert,淡出一个对象就是[object object],但是co ...

  5. [Javascript] Advanced Console Log Arguments

    Get more mileage from your console output by going beyond mere string logging - log entire introspec ...

  6. Eclipse中javascript文件 clg 变为console.log();

    Eclipse中javascript文件 clg 变为console.log(); window>preferance>JavaScript>Editor>Templates ...

  7. javascript中的console.log有什么作用?

    javascript中的console.log有什么作用? 主要是方便你调式javascript用的.你可以看到你在页面中输出的内容. 相比alert他的优点是:他能看到结构话的东西,如果是alert ...

  8. jquery对象和javascript对象的console.log结果

    array.push($("div").children("label")); console.log(array); 输出: 这个是jquery对象,如果在选 ...

  9. JavaScript调试技巧之console.log()详解--2015-08-07

    对于JavaScript程序的调试,相比于alert(),使用console.log()是一种更好的方式,原因在于:alert()函数会阻断 JavaScript程序的执行,从而造成副作用:而cons ...

随机推荐

  1. Ubuntu/Debian 8 安装 Intel realsense 摄像头驱动

    ## Make Ubuntu/Debian Up-to-date1. sudo apt-get update && sudo apt-get upgrade && su ...

  2. ubuntu下安装pdf编辑器Master PDF Editor

    在 ubuntu 上看一些 pdf 文档,自带的pdf阅读器不带编辑功能.推荐使用 master pdf editor 1. 安装QT sudo apt-get install qt-sdk 2. 下 ...

  3. matplotlib 画图

    matplotlib 画图 1. 画曲线图       Tompson = np.array([0, 0, 0, 0, 0.011, 0.051, 0.15, 0.251, 0.35, 0.44, 0 ...

  4. Tomcat启动项目时内存溢出问题如何解决

    在Eclipse中,内存溢出(报不能创建JAVA虚拟机错时,也可能是这里配错了.) 1.双击Tomcat,点击Open launch configuration,Arguments, 2.在VM ar ...

  5. 网站遭遇CC及DDOS攻击紧急处理方案

    检测访问是否是CC攻击的命令: 80口为网站的访问端口,可以根据实际情况进行修改 # netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: ' ...

  6. Java的初始化执行顺序(父类static变量->子类static变量->父类成员变量->父类构造器->成员变量->构造器->main函数)

    1. 引言 了解Java初始化的顺序,有助于理解Java的初始化机制和内存机制. 顺序:父类static变量->子类static变量->父类成员变量->父类构造器->成员变量- ...

  7. 基于Jenkins,docker实现自动化部署(持续交互)【转】

      前言 随着业务的增长,需求也开始增多,每个需求的大小,开发周期,发布时间都不一致.基于微服务的系统架构,功能的叠加,对应的服务的数量也在增加,大小功能的快速迭代,更加要求部署的快速化,智能化.因此 ...

  8. visual studio 2017 installer 安装包制作过程出现的问题---无法注册模块 HRESULT -2147024769 请与您的技术支持人员联系

    使用visual studio 2017 installer制作打包程序时如果用到了外部控件需要按以下方式操作: 1.将应用程序及应用程序所用到的所有DLL拷贝到打包目录,加入打包程序之中. 2.将应 ...

  9. 洛谷P1970 花匠

    传送门 首先可以知道,如果一个序列是连续上升的,那么只需要取这一个序列中最高的元素即可,因为取其它的不能保证大于后面的.连续下降的序列同理.而这些恰好就是波峰和波谷. 所以遇到 $ j $ 比之前的 ...

  10. Jmeter接口测试参数化实例图文示例

    在实际测试中,不可能查询值测试一个输入值,还有其他测试数据,故引入参数化的概念,让一条用例循环执行,直到所有测试数据均测试完成,如下示例: Jmeter参数化有4种方法,本例仅介绍最普遍及简单的1个方 ...