因为JavaScript的变量做用域其实是函数内部,咱们在for循环等语句块中是没法定义具备局部做用域的变量的:java
'use strict'; function foo() { for (var i=0; i<100; i++) { // } i += 100; // 仍然能够引用变量i }
为了解决块级做用域,ES6引入了新的关键字let,用let替代var能够申明一个块级做用域的变量:浏览器
'use strict'; function foo() { var sum = 0; for (let i=0; i<100; i++) { sum += i; } i += 1; // SyntaxError }
访问属性是经过.操做符完成的,但这要求属性名必须是一个有效的变量名。若是属性名包含特殊字符,就必须用''括起来:app
var xiaohong = { name: '小红', 'middle-school': 'No.1 Middle School' };
xiaohong的属性名middle-school不是一个有效的变量,就须要用''括起来。访问这个属性也没法使用.操做符,必须用['xxx']来访问:函数
xiaohong['middle-school']; // 'No.1 Middle School' xiaohong['name']; // '小红' xiaohong.name; // '小红'
也能够用xiaohong['name']来访问xiaohong的name属性,不过xiaohong.name的写法更简洁。code
咱们在编写JavaScript代码的时候,属性名尽可能使用标准的变量名,这样就能够直接经过object.prop的形式访问一个属性了。对象
因为JavaScript的对象是动态类型,你能够自由地给一个对象添加或删除属性:继承
var xiaoming = { name: '小明' }; xiaoming.age; // undefined xiaoming.age = 18; // 新增一个age属性 xiaoming.age; // 18 delete xiaoming.age; // 删除age属性 xiaoming.age; // undefined delete xiaoming['name']; // 删除name属性 xiaoming.name; // undefined delete xiaoming.school; // 删除一个不存在的school属性也不会报错
若是咱们要检测xiaoming是否拥有某一属性,能够用in操做符:索引
var xiaoming = { name: '小明', birth: 1990, school: 'No.1 Middle School', height: 1.70, weight: 65, score: null }; 'name' in xiaoming; // true 'grade' in xiaoming; // false
Note:若是in判断一个属性存在,这个属性不必定是xiaoming的,它多是xiaoming继承获得的:ip
'toString' in xiaoming; // true
由于toString定义在object对象中,而全部对象最终都会在原型链上指向object,因此xiaoming也拥有toString属性。ci
要判断一个属性是不是xiaoming自身拥有的,而不是继承获得的,能够用hasOwnProperty()方法:
var xiaoming = { name: '小明' }; xiaoming.hasOwnProperty('name'); // true xiaoming.hasOwnProperty('toString'); // false
javaScript把null、undefined、0、NaN和空字符串''视为false,其余值一律视为true,所以上述代码条件判断的结果是true。
for循环的一个变体是for ... in循环,它能够把一个对象的全部属性依次循环出来:
var o = { name: 'Jack', age: 20, city: 'Beijing' }; for (var key in o) { alert(key); // 'name', 'age', 'city' }
要过滤掉对象继承的属性,用hasOwnProperty()来实现:
var o = { name: 'Jack', age: 20, city: 'Beijing' }; for (var key in o) { if (o.hasOwnProperty(key)) { alert(key); // 'name', 'age', 'city' } }
因为Array也是对象,而它的每一个元素的索引被视为对象的属性,所以,for ... in循环能够直接循环出Array的索引:
var a = ['A', 'B', 'C']; for (var i in a) { alert(i); // '0', '1', '2' alert(a[i]); // 'A', 'B', 'C' }
请注意,for ... in对Array的循环获得的是String而不是Number。
全局变量会绑定到window上,不一样的JavaScript文件若是使用了相同的全局变量,或者定义了相同名字的顶层函数,都会形成命名冲突,而且很难被发现。
减小冲突的一个方法是把本身的全部变量和函数所有绑定到一个全局变量中。例如:
// 惟一的全局变量MYAPP: var MYAPP = {}; // 其余变量: MYAPP.name = 'myapp'; MYAPP.version = 1.0; // 其余函数: MYAPP.foo = function () { return 'foo'; };
把本身的代码所有放入惟一的名字空间MYAPP中,会大大减小全局变量冲突的可能。
许多著名的JavaScript库都是这么干的:jQuery,YUI,underscore等等。
因为var和let申明的是变量,若是要申明一个常量,在ES6以前是不行的,咱们一般用所有大写的变量来表示“这是一个常量,不要修改它的值”:
var PI = 3.14;
ES6标准引入了新的关键字const来定义常量,const与let都具备块级做用域:
'use strict'; const PI = 3.14; PI = 3; // 某些浏览器不报错,可是无效果! PI; // 3.14