因爲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