1. 程式人生 > 程式設計 >JavaScript 引用型別例項詳解【陣列、物件、嚴格模式等】

JavaScript 引用型別例項詳解【陣列、物件、嚴格模式等】

本文例項講述了JavaScript 引用型別。分享給大家供大家參考,具體如下:

陣列

在ECMAScript中陣列是非常常用的引用型別
ECMAScript所定義的陣列和其他語言中的陣列有著很大的區別
陣列也是一種物件

建立陣列

//方法一
var arr = new Array();

//方法二
var arr1 = [];

特點

  • 陣列即一組資料的集合

  • js陣列更加類似java的map容器。長度可變,元素型別任意

  • 陣列長度隨時可變!隨時可以修改!(length屬性)

    var arr1 = [123,324,true,'abc',1,4,5,new Date()];
    
    arr1.length = 5;
    
    console.log( arr1 );
    //log 裡面是傳遞的字串 , JS引擎預設會呼叫.toString(); 隱式的呼叫.
    

常用方法

push、pop
shift、unshift
splice、slice
concat、join、sort、reverse(逆序)

影響原陣列
splice()
arr.splice(開始項,[控制幾位數,值]); //statr,count,var arr = [1,2,3,6,7];
var zf = arr.splice(3); //控制幾位數, 預設值 :arr.length-1 //包括3 原來項數
console.log( arr ); //[1,3]
console.log( zf ); //[4,7] //返回值 -- 取出的內容

var arr = [1,7]; 
var zf = arr.splice(3,2); //擷取
console.log( arr ); //[1,7]
console.log( zf ); //[4,5] 

var arr = [1,7]; 
var t = arr.splice(3,'zf','dd'); //替換
console.log( arr ); //[1,'dd',7]
console.log( t ); //[4,5]

var arr = [1,'dd'); //插入
console.log(arr); //[1,7]
console.log( t ); //[] //如果為0,去除空陣列

var arr = [1,7]; 
var 12 = arr.splice(-4); //擷取
console.log( arr ); //[1,7]

//
slice(stat,end) //去出了end-stat 項。 不包括end項。

var zf = arr.sort(function ( a,b ) { //傳遞匿名函式,通過匿名函式引數判斷大小。
  if( a>b ){
    return 1;
  } else if( a<b ){
    return -1;
  } else {
    return 0;
  }
});
console.log( arr ); //["a","b","e","z"]
console.log( zf ); //["a","z"]

// 影響原陣列
push,pop,unshift,shift,splice,reverse,sort
// 未影響 原陣列
concat,slice,join

ES5陣列新特性

位置方法:indexOf lastIndexOf
迭代方法:every filter forEach some map
縮小方法:reduce reduceRight

// indexOf(); //查詢位置 

var arr = [234,23,45,46,645,56];

//1個引數的時候,表示傳值 返回索引位置
var idxVal = arr.indexOf(45);

//2個引數的時候, 第一個表示查詢的值,第二個引數是 傳值,表示起始開始查詢的起始位置
var idxVal = arr.indexOf(2,3);

//查詢陣列比較的時候 是 "===" 

//找不到返回 -1

//迭代方法

//every : 對於陣列每一個元素進行一個函式的執行 如果函式都返回true, 最後則返回true。 如果有一個返回false 最後結果則返回false。
// 測試陣列的所有元素是否都通過了指定函式的測試 

var arr = [1,6];

var reslut = arr.every(function ( item,index,array ) {
  
  return item > 0;
  
});

console.log( reslut ); //true

//filter : 對於陣列的每一個元素進行一個函式的執行 給定的函式執行, 把過濾後的結果返回。

var arr = [1,6];

var reslut = arr.filter(function ( item,array ) {
  
  return item > 2; //所有大於2 的過濾出來
  
})

console.log( reslut ); //[3,6]

//forEach : 迴圈陣列每一項, 並執行一個方法
// 方法中的引數:陣列成員的值,陣列成員的索引,原陣列(修改原陣列會影響原來遍歷的陣列)

var arr = [1,6];

arr.forEach(function ( item,array ) {
  
  console.log( item );
  
});

var arr1 = ['tan','cyan','pink','red'];
arr1.forEach(function ( val,idx,arrs ) {
  
  return 1; // 返回返回並不會影響原陣列
  
});
console.log(arr);

//map : 對於陣列的每一個元素進行一個函式的執行 可以經過函式執行完畢  把新的結果返回, 原陣列不變。

var arr = [1,6];

var reslut = arr.map(function ( item,array ) {
  
  return item * 3;
  
}); 

console.log( reslut ); //[3,9,12,18]

//some : 對於陣列每一個元素進行一個函式的執行 如果有一項返回true 最後則返回true 如果每一項都返回false, 最後才返回false。 

var arr = [1,6];

var reslut = arr.some(function ( item,array ) {
  
  return item > 5; //有一個返回true, 就返回true
  
});

console.log( reslut ); //true


//模擬filter方法
Array.prototype.filter = function ( cb ) {
  
  var reslut = [];
  
  try{
    
    if ( cb && cb.constructor === Function ) {
        
      for ( var i=0; i<this.length; i++ ) {
        
        if ( cb.call(this[i],this[i],i,this) ) {
          
          reslut.push(this[i]);
          
        }
    
      }
      
    }
    
  }catch(e){
    //TODO handle the exception
  }
  
  return reslut ? reslut : '';
  
}

var a = arr.filter(function ( item,arr ) {
  
  return item > 2;
  
});
console.log( a );

// 模擬some
Array.prototype.some = function ( fn ) {
  
  try{
    
    if ( fn && fn.constructor === Function ) {
      
      
      for ( var i=0; i<this.length; i++ ) {
        
        // 存在一個函式執行結果 為true , 返回true
        if ( fn.call(this[i],this) ) {
          
          return true;
          
        }
        
      }
      return false;
    }
    
  }catch(e){
    //TODO handle the exception
  }
  
}

var arr = [1,6];

// reduce reduceRight

// 前一個值, 當前值, 索引位置, array 
// 陣列中的每個值(從左到右)開始合併,最終為一個值。
// 接收一個函式作為累加器,陣列中的每一個值(從左到右)開始合併,最終為一個值。
var reslut = arr.reduce(function ( prev,cur,array ) {
  
  return prev + cur;
  
});

console.log( reslut ); //25

// reduceRight 從右開始遍歷
var reslut1 = arr.reduceRight(function ( prev,array ) {
  
  return prev + cur;
  
});

console.log( reslut ); //25


// 得到介面的物件

var o = (function() {
  var person = {
    name: 'xixi',age: 22,}
  return {
    sayName: function(k) {
      return person[k];
    },}
}());

var person = ['name','age'].reduce(function (obj,k) {
//   console.log(obj,k,'--');
  obj[k] = o.sayName(k);
  return obj;
},{});

console.log(person);

陣列判斷方法:
Array.isArray();
判斷是否為陣列,如果是,則返回true,否則返回false。

var arr = [];
console.log( Array.isArray(arr) );

填充方法:
fill();
實現對陣列的填充
引數:接受值,直接填充,如果是函式,也是直接填充

// arr.fill(1);
// arr.fill(function () {
//   return 2;
// });
// arr.fill([1,3]);
arr.fill({x: 1});

console.log(arr);

Object

引用型別都是Object型別的例項,Object也是ECMAScript中使用最多的一種型別(就像java.lang.Object一樣,Object型別是所有它的例項的基礎) //所有類的 基礎類。

Object型別的建立方式、使用

對於Object型別應用for in 列舉迴圈

Obj每個例項都具有屬性和方法

Constructor: 儲存著用於建立當前物件的函式。(建構函式)

hasOwnProperty(propertyName):用於檢測給定的屬性在當前物件例項中(而不是原型中)是否存在。

isPrototypeOf(Object): 用於檢查傳入的物件是否是另外一個物件的原型。

propertyIsEnumerable(propertyName):用於檢查給定的屬性是否能夠使用for-in語句來列舉。

toLocaleString():返回物件的字串表示。該字串與執行環境的地區對應.

toString():返回物件的字串表示。

valueOf():返回物件的字串、數值或布林表示。

OBject.prototype.toString()

Object.prototype.toString
作用:根據內部的this返回一個類似於這樣的字串 [object constructorName]
這個方法有個缺點,不能獲取使用者自定義物件的具體型別.
只能獲取內建物件的型別.
自定義物件型別都返回:[object Object]

console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(Array)); // [object Fcuntion]
console.log(Object.prototype.toString.call(new Date())); // [object Date]

// 簡寫方式
console.log(({}).toString.call([])); // [object Array]

toString();

// 字串 ==> String.prototype.toString();
var a = 't';
console.log(a.toString()); // t
var a = new String(); 
console.log(a.toString()); // 空字串
var a = new String('string');
console.log(a.toString());  // string

// 陣列 ==> Array.prototype.toString();
var b = [1,4];
console.log(b.toString()); // 1,4
var b = [];
console.log(b.toString()); // 空字串
var b = new Array();
console.log(b.toString()); // 空字串
var b = new Array(3,5);
console.log(b.toString()); // 3,5

// 物件 ==> Object.prototype.toString();
var c = {};
console.log(c.toString()); // [object Object]

// 函式
console.log(Function.toString()); // function Function() { [native code] }
console.log(Array.toString()); // function Array() { [native code] }
console.log(RegExp.toString()); // function RegExp() { [navtive code] }

關於JSON函式

JSON.parse()

作用:將JSON字串解析成JavaScirpt值。在解析過程中,可以選擇性的修改某些屬性的原始解析值。
引數1:JSON字串
引數2: reviver 函式,用來轉換解析出的屬性值。(可選引數)
返回值:解析出的一個 Object

console.log(JSON.parse(10)); // 10
console.log(JSON.parse(true)); // true
console.log(JSON.parse('"xixi"')); // xixi
console.log(JSON.parse(null)); // null
console.log(JSON.parse('"undefined"')); // undefined
console.log(JSON.parse("[]")); // []

如果指定了 reviver 函式,解析的出的Object,解析值本身以及它所包含的所有屬性,會按照一定的順序(從最最裡層的屬性開始,一級級往外,最終到達頂層)分別去呼叫 指定的reviver 函式。

在呼叫過程中,當前屬性所屬的物件會作為this值,當前屬性名和屬性值會分別作為第一個引數和第二個引數傳入 reviver 函式中,如果 reviver 函式返回undefeind,則當前屬性會從屬性物件中刪除,如果返回了其它值,則返回的值會成為當前屬性新的屬性值。
當遍歷到最頂層的值(解析值)時,傳入reviver函式的引數會是空字串''(因為此時已經沒有真正的屬性)和當前的解析值(有可能已經被修改過),當前的this值會是{"":修改過的解析值},

JSON.parse('{"p": 5}',function (key,val) {

 if(key === '') return val;   // 如果到了最頂層,則直接返回屬性值
  
 return val * 2;
  
}); 

JSON.stringify();

stringify(value [,replacer,[space]]);
將任意的JavaScript值序列化成JSON字元
引數1:value: 將序列化成JSON字串的值
引數2:replacer: 可選,如果是一個函式,則在序列化過程中,被序列化的值的每個屬性都會經過該函式的轉換和處理。 如果是一個數組,則暴行在這陣列中的屬性名才會被序列化到最終的JSON字串中。
引數3:space, 指定縮排可通的空白字串,用於美化輸出。 控制結果字串裡的間距。

注意:

  • 不可列舉的屬性會被忽略

  • 非陣列物件的屬性不能保證以特定的順序出現的序列化後的字串中。

  • 布林值,數字,字串的包裝物件在序列化過程中會自動裝換成對應的原始值。

  • undefeind,任意的函式,以及symbol值,在徐淚花過程橫縱揮別忽略(出現在非陣列物件的屬性值中時)或者被轉換成null(出現在陣列中時)

  • 所有以symbol為屬性鍵的屬性值都會被完全忽略掉,即便 replacer引數中強制指定包含了它們

    console.log(JSON.stringify([undefined,Object,Symbol()])); // null,null,null
    console.log(JSON.stringify({x: undefined,y: Object,z: Symbol()})); // {}
    

Object.create

ES5為物件提供了一個Object.create();
作用:建立一個類,是一種寄生式繼承。
返回一個類,這個類的原型指向傳遞進來的物件。

建立的例項化物件,建構函式指向的是繼承的物件的類的建構函式。本身沒有原型,可以通過原型鏈找到繼承的物件類中的原型。具有繼承物件上的屬性以及方法。
因此,建立的例項化物件可以使用繼承物件上的屬性和方法。

var Book = function (title,price) {
  
  this.title = title;
  
  this.price = price;
  
}

Book.prototype.sayTitle = function () {
  
  return this.price;
  
}

var book = new Book('one',10);

// 建立一個繼承類
var NewBook = Object.create(book);

console.log(NewBook.constructor);

var price = NewBook.sayTitle();

console.log(price);

// 模擬 Object.create();
// 寄生式繼承
Object.prototype.create = function ( obj ) {
  
  try{
    
    if ( obj && obj.constructor === Object ) {
      
      function F () {}
      
      F.prototype = obj;
      
      return F;
      
    }
      
    
  }catch(e){
    //TODO handle the exception
  }
  
}

// 建立一個繼承類
var NewBook = Object.create(book);

console.log(NewBook.constructor);

var price = NewBook.sayTitle();

console.log(price);

Object.defineProperty

Object.defineProperty();
直接在一個物件上定義一個新屬性,或者修改一個已經存在的屬性,並返回這個物件。
引數1:需要被設定的物件
引數2:設定的屬性名
引數3:配置項,新增屬性的特性屬性

特性屬性:
value:該屬性值,預設值:undefeind
writable: 可否被修改,預設值:false (不能被修改)
configuarable: 能否通過delete刪除屬性從而重新定義屬性,能夠修改屬性的特性,或者能否把屬性修改為訪問屬性。 預設值:false;(不可以重新定義或刪除)
enumerable: 是否可以被for-in列舉。預設值:false

var obj = {};

Object.defineProperty(obj,'title',{
  
  value: 'tan',//        writable: true,configurable: false,//        enumerable: true
  
});

delete obj.title;

//      obj.title = 'pink';

//      for ( var i in obj ) {
//        
//        console.log(obj[i]);
//        
//      }

console.log(obj);

特性方法:
set:給屬性提供setter的方法,如果沒有setter則為undefined。預設值undefiend。
引數:該引數的新值分配給該屬性。預設:undefined

Object.defineProperty(obj,{
  
  get: function () {
    console.log('get');
    return this._title;
  },set: function ( val ) {
    this._title = val;
  }
  
});

obj.title = 'pink';

var t = obj.title;

defineProperties

在一個物件上新增或修改一個或多個自有屬性,並返回該物件。
引數1:表示要被處理的物件
引數2:定義多個屬性特性物件

var obj = {}

Object.defineProperties(obj,{
  
  color: {
    value: 'tan'
  },names: {
    value: 'zf'
  }
  
});

console.log( obj );

getOwnPropertyNames

Object.getOwnPropertyNames();
返回一個由指定物件的所有自身屬性的屬性名(包括不可列舉屬性)組成的陣列。
引數:需要獲取的物件。

getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor();
指定物件上一個自由屬性對應的屬性描述符。(自由屬性指的直接賦予該物件的屬性,不需要從原型鏈上進行查詢的屬性)
引數1: 獲取的物件。
引數2:獲取的屬性值

模擬map

模擬java中的Map

    
//簡單實現 map

function Map () {
  
  //priveate 的物件來儲存 key 和 val
  var obj = {};
  
  // put 方法
  this.put = function ( key,val ) {
    
    
    obj[key] = val;  //把鍵值對 繫結到object上.
    
  }
  
  //獲得map 容器的個數
  this.size = function () {
    
    var count = 0;
    
    for ( var i in obj ) {
      
      count++;
      
    }
    
    return count;
    
  }
  
  //根據key 得到 val
  this.get = function ( key ) {
    
    return obj[key] || (obj[key] === 0) || (obj[key] === false) ? obj[key] : null;
    
  }
  
  // remove 刪除方法
  this.remove = function ( key ) {
    
    if ( obj[key] || obj[key] === 0 || obj[key] === false ) delete obj[key]; 
    
  }
  
  //eachMap 遍歷 map 容器的方法
  this.eachMap = function ( cb ) {
    
    if ( cb && cb.constructor === Function ) {
      
      for ( var i in obj ) {
        
        cb.call(this,obj[i]);
        
      }
      
    }
    
  }
  
}

var m = new Map();

m.put('01',120);
m.put('02','tan');

//      console.log( m.size() );
//      
//      console.log( m.get('0') );

//      m.remove('01');
//      console.log( m.get('01'),'--' );

m.eachMap(function ( key,val ) {
  
  console.log( key,val,'---' );
  
});    

去掉陣列的重複項

var arr = [1,546,57,31,57];

//js 物件特性, 陣列去重 
// 在 js 物件 中 key 是永遠 不會重複的.


// 1, 把陣列轉成一個js的物件
// 2,把陣列中的值,變成js 物件當中的key
// 3,把物件再還原成陣列

//陣列轉物件
var toObject = function ( arr ) {
  
  var reslutObj = {};
  
  for ( var i=0; i<arr.length; i++ ) {
    
    if ( arr ) {
    
      reslutObj[arr[i]] = null; //賦值為任意值
      
    }
    
  }
  
  return reslutObj;
  
}

//物件轉成陣列
var toArray = function ( obj ) {
  
  var reslutArr = [];
  
  for ( var attr in obj ) {
    
    if ( obj.hasOwnProperty(attr) ) { //判斷是否是自身上面的屬性
      
      reslutArr.push(attr);
      
    }
    
  }
  
  return reslutArr;
  
}

//去掉陣列中的重複項
function uniq ( arr ) {
        
  return toArray(toObject(arr));
        
}
  
console.log( uniq(arr) );  

其他引用型別

單體物件(不需要例項化物件,就可以使用的方法):

Global物件(全域性)這個物件不存在,無形的物件(特別的,特殊的存在)
其內部定義了一些方法和屬性:encodeURI 、encodeURIComponent、decodeURI、decodeURIComponent、eval、parseInt、parseFloat、isNaN(在js 裡面 只有NaN 自己不等於自己本身的)、Escape、 unescape

// encodeURI 、encodeURIComponent、

var uri = 'http://www.baidu.com cn';
var str1 = encodeURI(uri); //http://www.baidu.com%20cn         //(url: //不會進行編碼)
var str2 = encodeURIComponent(uri); //http%3A%2F%2Fwww.baidu.com%20cn //任何不標準的文字都會進行編碼

console.log( str1 );
console.log( str2 );

// decodeURI、decodeURIComponent、
console.log( decodeURI(str1) ); // http://www.baidu.com cn
console.log( decodeURIComponent(str2) ); // http://www.baidu.com cn

//eval(string) 方法 無形的javascript 解析器

var str1 = 'var a = 10; var b = 20;';
eval(str1);

console.log( a+b );

//陣列字串 直接使用: eval(strArr);

var arr = '[10,203,345,6]';

var evalArr = eval(arr);

console.log( evalArr );

//物件字串 
var obj = '{name: "123",age: 20}';

var evalObj = eval('(' + obj + ')' );

console.log( evalObj );//Object {name: "123",age: 20}

//escape unescape URI 轉碼
var str = '八百米';
var str2 = escape(str); //%u516B%u767E%u7C73

console.log( str2 );

Math物件
內建的Math物件可以用來處理各種數學運算
可以直接呼叫的方法:Math.數學函式(引數)
求隨機數方法:Math.random(),產生 [0,1) 範圍一個任意數

Date物件
獲取當前時間的一系列詳細方法

var date = new Date();

console.log( date.getTime() );   //當前時間的毫秒數

基本包裝型別:Boolean、String、Number

Function型別、RegExp型別

簡單單體和閉包單體

單體(singleton)模式是js中最基本但又最有用的模式之一,它可能比其他任何模式都常用。
這種模式提供了一種將程式碼組織為一個邏輯單元的手段,這個邏輯單元中的程式碼可以通過單一的變數進行訪問。通過確保單體物件只存在一份例項,就可以確信自己的所有程式碼使用的都是同樣的全域性資源。

簡單單體

// 簡單單體模式  (只能建立一個例項)//無法通過new 關鍵字來例項化.
var Singleton = { //當成模板類 
  attr1: true,attr2: 10,method1: function () {
    
    console.log( this.attr1 );
    
  }
  
}

Singleton.method1();

//劃分名稱空間(區分程式碼)
  

閉包單體

//  利用閉包來建立單體,閉包主要的目的 , 保護資料

var alogy = {};
alogy.singleton = (function () {
  
  
  //新增私有成員
  
  var a = 100;
  var fn1 = function () {
    
    console.log( a );              
    
  }
  
  // 塊級作用域裡的執行結果賦值 單體物件
  return {
    attr1: 10,attr2: 20,method: function () {
      console.log( this.attr1 );
    },fn1: fn1
  }
    
    
})();

alogy.singleton.method();
alogy.singleton.fn1();  

惰性單體

//惰性單體 (和閉包單體類似)

//通過 一個私有變數來控制是否 例項化物件, 初始化一個 init。

var Ext = {};

Ext.Base = (function () {

//私有變數 控制返回的單體物件
var uniqInstance; 

//需要一個構造器 init 初始化單體物件的方法
function Init () {
  
  //私有成員
  var a1 = 10;
  var a2 = true;
  
  var fun1 = function () {
    
    console.log( a1 );
    
  }
  
  return {
    attr1: a1,attr2: a2,fun1: fun1
  }
  
}

return {
  
  getInstance: function () {
    
    if ( !uniqInstance ) { //不存在 ,建立單體例項
      
      uniqInstance = new Init();          
      
    }
    
    return uniqInstance;
    
  }
  
}

})()

var init = Ext.Base.getInstance();

init.fun1(); //10

分支單體

//分支單體 (判斷程式的分支 - 瀏覽器差異的檢測)
//簡單判斷
var Ext = {};

var def = true; 

Ext.More = (function () {
  
  var ff = {
    attr1: 'ff'
  };
  
  var ie = {
    attr1: 'ie'
  }
  
  return def ? ff : ie;
  
})()

console.log( Ext.More.attr1 ); //ff

簡單鏈式程式設計實現

簡單鏈式呼叫。 return this;

//簡單函式鏈式呼叫 

function Dog () {
  
  this.run = function () {
    
    console.log( 'dog is run...' );
    
    return this;
    
  }
  
  this.eat = function () {
    
    console.log( 'dog is eat...' );
    
    return this;
    
  }
  
  this.slepp = function () {
    
    console.log('dog is sleep');
    
    return this;
    
  }
  
}

var d1 = new Dog();

d1.run().eat().slepp();
   

模擬jquery底層程式碼

//模擬jquery底層鏈式程式設計
  
// 函式自執行 特點:
// 1: 程式啟動時候  裡面程式碼自動執行
// 2: 內部的成員變數 外部無法訪問 (除了不加var修飾的變數)

//塊級 作用域  

(function ( window,undefined ) {
  
  //$ 最常用的物件 返回給外界 //大型程式開發  一般使用 '_'作為私有的物件
    
  function _$ ( args ) {
    
    // 匹配id 選擇器
    var idSelect = /^\#[\w+]?/;
    
    this.dom; // 接收所得到的元素
    
    if ( idSelect.test(args) ) { //匹配成功接收元素 // #div 
      
      this.dom = document.getElementById(arguments[0].substr(1));
    
    } else {
      
      throw new Error('選擇器不正確!');
      
    }
    
  }
  
  //在Function類上 擴充套件 一個可以實現 鏈式程式設計的方法
  Function.prototype.method = function ( methodName,fn ) { //實現鏈式程式設計, 方法的名字 和 進行呼叫的函式是什麼
    
    this.prototype[methodName] = fn;
    
    return this; //鏈式程式設計
    
  }
  
  // 在 _$ 原型物件上 加一些公共的方法
  _$.prototype = {
    
    constructor: _$,addEvent: function ( type,cb ) {
      
      //ff chrome
      if ( window.addEventListener ) { 
        
        this.dom.addEventListener(type,cb,false);
        
      //ie
      } else if ( window.attachEvent ) { 
        
        this.dom.attachEvent('on'+type,cb);
        
      }
  
      return this;
      
    },setStyle: function ( key,val ) {
      
      this.dom.style[key] = val;
      
      return this;
      
    }
    
  }
  
  //window上註冊 一個 全域性變數
  window.$ = _$;
  
  //準備方法
  _$.onReady = function ( cb ) {
    
    //1,例項化 _$ 物件 ,註冊到 window上
    window.$ = function ( args ) {
      
      return new _$(args); 
      
    }
    
    //2: 執行傳入的程式碼
    cb.call(window);
    
    //3: 實現鏈式程式設計 
    _$.method('addEvent',function () {}).method('setStyle',function () {});
    
  }
  
})( window ) //程式的入口 window傳入作用域中      

$.onReady(function () {
  
  $('#div')
  .addEvent('click',function () {
    
    console.log('點選了');
    
  })
  .setStyle('background','pink')
  
});

嚴格模式

嚴格模式是JavaScript中的一種限制性更強的變種方式。
嚴格模式與非嚴格模式可以共存,可以逐漸的選擇性加入嚴格模式。

全域性作用域

定義變數必須通過var
嚴格模式禁止刪除宣告變數。

delete關鍵字

使用delete刪除一個變數名(而不是屬性名): delete myVariable

'use strict';

delete Object.prototype; // error . 
// 刪除一個不可配置的屬性

函式引數

定義相同名稱的引數
要求引數名唯一。
在正常模式下,最後一個重名引數名諱覆蓋之前的重名引數,之前的引數仍然可以通過arguments[i]來訪問,還不是完全無法訪問。

關鍵字,保留字

使用eval或arguments作為變數名或函式名

嚴格模式下:
訪問arguments.callee,arguments.caller,anyFunction.caller以及anyFunction.arguments都會丟擲異常

禁止使用八進位制

瀏覽器都支援以零(0)開頭的八進位制語法:0644 == 420 還有 '\045 === '%''
認為數字的前導零沒有語法意義,但是會改變數字的意義。

eval

嚴格模式下不能向全域性作用域下新增變數

在正常模式下,程式碼eval('var x;') 會給上層函式或全域性引入一個新的變數 x
嚴格模式下,eval為被執行的程式碼建立變數,eval不會影響到名稱對映到外部變數或其它區域性變數。

var x = 22;

var evalX = eval("var x = 42; x");

console.log(x === 22);
console.log(evalX === 42);

函式內部this

在正常模式下函式呼叫,this的值會指向全域性物件,在嚴格模式中,this的值會指向undefiend。

當函式通過call和apply呼叫時,如果傳入的是thisvalue引數是一個null和undefiend除外的原始值(字串,數字,布林值),則this的值會成為那個原始值的對應的包裝物件。如果thisavlue引數的值是undefeind或null,則this的值會指向全域性變數。在嚴格模式中,this值就是thisvalue引數的值,沒有任何型別轉換。

this: 僅在this指向自己建立的物件時使用它

arguments

arguments物件屬性不語對應的形參變數同步更新。
非嚴格模式下,修改arugmetns物件中的某個索引屬性的值,和這個屬性對應的形參變數的值也會同時變化。
嚴格模式下,arguments物件會以形參變數的拷貝的形式被建立和初始化。因此arguments物件的改變不會影響形參。

arguments: 總是通過形參的名字獲取函式引數,或者在函式的第一行拷貝arguments

var args = Array.prototype.slice.call(arguments)

with

嚴格模式禁用with。
with問題:塊內的任何變數都可以對映到with傳進來的物件的屬性,也可以對映到包圍這個塊的作用域內的變數(甚至是全域性變數),在執行時才能夠決定:在程式碼執行之前無法得到。
嚴格模式下,使用with會引起語法錯誤。

var x = 7;
with (obj) { // 語法錯誤
 // 如果沒有開啟嚴格模式,with中的這個x會指向with上面的那個x,還是obj.x?
 // 如果不執行程式碼,我們無法知道,因此,這種程式碼讓引擎無法進行優化,速度也就會變慢。
 x;
}

感興趣的朋友可以使用線上HTML/CSS/JavaScript程式碼執行工具:http://tools.jb51.net/code/HtmlJsRun測試上述程式碼執行效果。

更多關於JavaScript相關內容感興趣的讀者可檢視本站專題:《javascript面向物件入門教程》、《JavaScript錯誤與除錯技巧總結》、《JavaScript資料結構與演算法技巧總結》、《JavaScript遍歷演算法與技巧總結》及《JavaScript數學運算用法總結》

希望本文所述對大家JavaScript程式設計有所幫助。