1. 變量。javascript
使用全局變量需注意:java
1. 全局變量的泛濫使用會致使變量覆蓋,出現意想不到的問題。jquery
2. 破壞代碼的可移植性。json
3. 使用var避免全局變量。閉包
預解析:var的散佈問題模塊化
JavaScript中,你能夠在函數的任何位置聲明多個var語句,而且它們就好像是在函數頂部聲明同樣發揮做用,這種行爲稱爲 hoisting(懸置/置頂解析/預解析)。函數
JavaScript有一個特性叫作隱式全局變量,無論一個變量有沒有用過,JavaScript解釋器反向遍歷做用域鏈來查找整個變量的var聲明,若是沒有找到var,解釋器則假定該變量是全局變量,若是該變量用於了賦值操做的話,以前若是不存在的話,解釋器則會自動建立它。這就是函數內部變量不加var會被解釋成全局變量的緣由。性能
var myname = 'global'; function show(){ console.log(myname); } show(); // global function show2(){ console.log(myname); var myname = 'show2'; } show2() // undefined function show3(){ console.log(myname); var myname = 'show2'; console.log(myname); } show3() // undefined show2
2. for循環。this
for(var i=0; i< myarr.length; i++){ // }
若是這是一個對象的話,每次都要去查找對象的屬性,影響性能,咱們能夠這樣寫:spa
var i, myarr = []; for(i = myarr.length;i--;){ // }
for in 遍歷對象屬性。若是繼承了,會查找原型鏈,遍歷到原型中的屬性,這不是指望的
for(n in obj){ if(obj.hasOwnProperty(i)){ // } }
3. 命名規範。
方法名按照駝峯命名法命名,由new調用的構造方法,首字母大寫,通常方法首字母小寫。
變量名統一用下劃線隔開單詞的命名法。封裝的私有方法,用下劃線開頭。
4. js的module模式。
基本特徵:
// 實現對象的公,私封裝 var Man = function(){ // 能夠在這裏定義全部的私有屬性 var name = '張三'; return { //暴露公有的接口 echo: function(){ console.log(name); } } } var m1 = new Man() m1.echo()
匿名函數的兩種閉包方式
//第一種 (function(){}()) //第二種 (function(){})() //習慣使用第一種
爲閉包引入全局變量
(function($){ //可使用$訪問jquery對象了 }(jQuery))
上面使用了全局變量,若是我想聲明全局變量呢?
var blog = (function(){ //聲明一個my對象來存儲定義的方法和屬性,這個是閉包的局部變量,其實就是全局的blog對象 var my = {}, _name = '博客'; my.Name = _name; //給全局blog添加屬性和方法 my.show = function(){ console.log(this.Name); } return my; }()) blog.Name // 博客
若是我想前面若是定義了blog就繼承(在原來的基礎上擴展),若是沒有就定義呢?
var blog = (function(my){ my.Name = '博客'; my.show = function(){ } return my; }(blog || {}))
又有問題了,我想重載blog方法呢?
//文件1.js var blog = { show: function(){ console.log(111); } }; //文件2.js,重載blog var blog = (function(my){ var oldShow = my.show; my.show = function(){ oldShow(); console.log(222); } }(blog))
建立子模塊
blogModule.CommentSubModule = (function () { var my = {}; // ... return my; } ());
當即調用方法的典型使用:
//給每一個對象綁定一個方法,點擊顯示該對象的索引 var elems = document.getElementsByTagName('a'); for (var i = 0; i < elems.length; i++) { elems[i].addEventListener('click', function (e) { e.preventDefault(); alert('I am link #' + i); }, 'false'); } //結果,全部點擊都顯示 I am link 10 var a = document.getElementById('results').getElementsByTagName('a'); for (var i = 0; i < a.length; i++){ a[i].addEventListener('click', (function(n){ return function(){ console.log(n); } }(i)), false) }
5. prototype和__proto__。
prototype和__proto__
__proto__是對象的默認私有屬性,經過__proto__屬性來造成原型鏈,查找對象的屬性。
prototype 是構造器的原型。
例如:
var person = {};
這是一個對象,因此是有__proto__屬性的,就是object對象。而它是沒有prototype屬性的。
var Person = function(name){ this.name = name; }
這是一個構造器,是有prototype屬性的
Person.prototype.say = function(){ console.log(this.name); }
他們有什麼聯繫呢?
var person = new Person('張三');
person是對象,全部應該有__proto__
實際上 person.__proto__ === Person.prototype === Object
接下來講說繼承。
直接用對象實現繼承
var student = { __proto__: new Person('張三同窗') } student.say(); //張三同窗
用構造器來繼承:
var Student = function(){} Student.prototype = new Person('張三同窗'); var student = new Student(); student.say(); //張三同窗
6. 閉包。.
閉包是代碼塊(bar函數)和建立該代碼塊的上下文中數據(foo函數的做用域)的結合。
函數是「第一類」對象。這個名詞意味着函數能夠做爲參數被傳遞給其餘函數使用 ,接收該函數參數的函數就稱爲高階函數。
function foo() { var x = 10; return function bar() { console.log(x); }; } // "foo"返回的也是一個function // 而且這個返回的function能夠隨意使用內部的變量x var returnedFunction = foo(); // 全局變量 "x" var x = 20; // 支持返回的function returnedFunction(); // 結果是10而不是20
這種形式的做用域稱爲靜態做用域。
共享靜態做用域
function baz() { var x = 1; return { foo: function foo() { return ++x; }, bar: function bar() { return --x; } }; } var closures = baz(); console.log( closures.foo(), // 2 closures.bar() // 1 );
7. 標準的JSON格式。
以前一直覺得JSON也是對象,如今才發現是一種錯誤的理解,json其實就是字符串的一種格式。
// 這是JSON字符串 var foo = '{ "prop": "val" }'; // 這是對象字面量 var bar = { "prop": "val" }; var obj = JSON.parse(foo); console.log(obj.prop) var str = JSON.stringify(bar); console.log(str); // { "prop": "val" }
JSON有很是嚴格的語法,冒號兩邊的數據必須都有引號,而且必須是雙引號,單引號就不行。
8. javascript的DOM
(非IE,ie的event也屬於window)
Event事件。
//ie 和 非ie function show(e){ e = e || window.event; e.preventDefault(); // 阻止默認行爲 e.stopPropagation(); // 阻止事件冒泡 }