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程式設計有所幫助。