javascript進階核心

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模式。

    基本特徵:

  1. 模塊化,可重用
  2. 封裝了變量和function,和全局的namaspace不接觸,鬆耦合
  3. 只暴露可用public的方法,其它私有方法所有隱藏。 
// 實現對象的公,私封裝

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();  // 阻止事件冒泡
}
相關文章
相關標籤/搜索