JavaScript 引用類型實例詳解【數(shù)組、對象、嚴(yán)格模式等】
本文實例講述了JavaScript 引用類型。分享給大家供大家參考,具體如下:
數(shù)組
在ECMAScript中數(shù)組是非常常用的引用類型
ECMAScript所定義的數(shù)組和其他語言中的數(shù)組有著很大的區(qū)別
數(shù)組也是一種對象
創(chuàng)建數(shù)組
//方法一 var arr = new Array(); //方法二 var arr1 = [];
特點
-
數(shù)組即一組數(shù)據(jù)的集合
-
js數(shù)組更加類似java的map容器。長度可變,元素類型任意
-
數(shù)組長度隨時可變!隨時可以修改!(length屬性)
var arr1 = [123,324,true,'abc',1,4,5,new Date()]; arr1.length = 5; console.log( arr1 ); //log 里面是傳遞的字符串 , JS引擎默認(rèn)會調(diào)用.toString(); 隱式的調(diào)用.
常用方法
push、pop
shift、unshift
splice、slice
concat、join、sort、reverse(逆序)
影響原數(shù)組 splice() arr.splice(開始項,[控制幾位數(shù),值]); //statr ,count , var arr = [1,2,3,4,5,6,7]; var zf = arr.splice(3); //控制幾位數(shù), 默認(rèn)值 :arr.length-1 //包括3 原來項數(shù) console.log( arr ); //[1,2,3] console.log( zf ); //[4,5,6,7] //返回值 -- 取出的內(nèi)容 var arr = [1,2,3,4,5,6,7]; var zf = arr.splice(3,2); //截取 console.log( arr ); //[1, 2, 3, 6, 7] console.log( zf ); //[4,5] var arr = [1,2,3,4,5,6,7]; var t = arr.splice(3,2,'zf','dd'); //替換 console.log( arr ); //[1,2,'zf','dd',6,7] console.log( t ); //[4,5] var arr = [1,2,3,4,5,6,7]; var t = arr.splice(3,0,'zf','dd'); //插入 console.log(arr); //[1,2,3,'zf','dd',4,5,6,7] console.log( t ); //[] //如果為0 ,去除空數(shù)組 var arr = [1,2,3,4,5,6,7]; var 12 = arr.splice(-4); //截取 console.log( arr ); //[1,2,3] console.log( zf ); //[4,5,6,7]
// slice(stat,end) //去出了end-stat 項。 不包括end項。
var zf = arr.sort(function ( a,b ) { //傳遞匿名函數(shù),通過匿名函數(shù)參數(shù)判斷大小。
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", "b", "e", "z"]
// 影響原數(shù)組
push , pop ,unshift ,shift ,splice ,reverse ,sort
// 未影響 原數(shù)組
concat ,slice ,join
ES5數(shù)組新特性
位置方法:indexOf lastIndexOf
迭代方法:every filter forEach some map
縮小方法:reduce reduceRight
// indexOf(); //查找位置 var arr = [234,23,45,46,45,645,56]; //1個參數(shù)的時候,表示傳值 返回索引位置 var idxVal = arr.indexOf(45); //2個參數(shù)的時候, 第一個表示查詢的值,第二個參數(shù)是 傳值,表示起始開始查詢的起始位置 var idxVal = arr.indexOf(2,3); //查找數(shù)組比較的時候 是 "===" //找不到返回 -1
//迭代方法
//every : 對于數(shù)組每一個元素進(jìn)行一個函數(shù)的運行 如果函數(shù)都返回true, 最后則返回true。 如果有一個返回false 最后結(jié)果則返回false。
// 測試數(shù)組的所有元素是否都通過了指定函數(shù)的測試
var arr = [1,2,3,4,3,2,4,6];
var reslut = arr.every(function ( item,index,array ) {
return item > 0;
});
console.log( reslut ); //true
//filter : 對于數(shù)組的每一個元素進(jìn)行一個函數(shù)的運行 給定的函數(shù)執(zhí)行, 把過濾后的結(jié)果返回。
var arr = [1,2,3,4,3,2,4,6];
var reslut = arr.filter(function ( item,index,array ) {
return item > 2; //所有大于2 的過濾出來
})
console.log( reslut ); //[3, 4, 3, 4, 6]
//forEach : 循環(huán)數(shù)組每一項, 并執(zhí)行一個方法
// 方法中的參數(shù):數(shù)組成員的值,數(shù)組成員的索引,原數(shù)組(修改原數(shù)組會影響原來遍歷的數(shù)組)
var arr = [1,2,3,4,3,2,4,6];
arr.forEach(function ( item,index,array ) {
console.log( item );
});
var arr1 = ['tan', 'cyan', 'pink', 'red'];
arr1.forEach(function ( val, idx, arrs ) {
return 1; // 返回返回并不會影響原數(shù)組
});
console.log(arr);
//map : 對于數(shù)組的每一個元素進(jìn)行一個函數(shù)的運行 可以經(jīng)過函數(shù)執(zhí)行完畢 把新的結(jié)果返回, 原數(shù)組不變。
var arr = [1,2,3,4,3,2,4,6];
var reslut = arr.map(function ( item,index,array ) {
return item * 3;
});
console.log( reslut ); //[3, 6, 9, 12, 9, 6, 12, 18]
//some : 對于數(shù)組每一個元素進(jìn)行一個函數(shù)的運行 如果有一項返回true 最后則返回true 如果每一項都返回false, 最后才返回false。
var arr = [1,2,3,4,3,2,4,6];
var reslut = arr.some(function ( item,index,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,index,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++ ) {
// 存在一個函數(shù)執(zhí)行結(jié)果 為true , 返回true
if ( fn.call(this[i], this[i], i, this) ) {
return true;
}
}
return false;
}
}catch(e){
//TODO handle the exception
}
}
var arr = [1,2,3,4,3,2,4,6];
// reduce reduceRight
// 前一個值, 當(dāng)前值, 索引位置, array
// 數(shù)組中的每個值(從左到右)開始合并,最終為一個值。
// 接收一個函數(shù)作為累加器,數(shù)組中的每一個值(從左到右)開始合并,最終為一個值。
var reslut = arr.reduce(function ( prev,cur,index,array ) {
return prev + cur;
});
console.log( reslut ); //25
// reduceRight 從右開始遍歷
var reslut1 = arr.reduceRight(function ( prev,cur,index,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);
數(shù)組判斷方法:
Array.isArray();
判斷是否為數(shù)組,如果是,則返回true,否則返回false。
var arr = []; console.log( Array.isArray(arr) );
填充方法:
fill();
實現(xiàn)對數(shù)組的填充
參數(shù):接受值,直接填充,如果是函數(shù),也是直接填充
// arr.fill(1);
// arr.fill(function () {
// return 2;
// });
// arr.fill([1,2,3]);
arr.fill({x: 1});
console.log(arr);
Object
引用類型都是Object類型的實例,Object也是ECMAScript中使用最多的一種類型(就像java.lang.Object一樣,Object類型是所有它的實例的基礎(chǔ)) //所有類的 基礎(chǔ)類。
Object類型的創(chuàng)建方式、使用
對于Object類型應(yīng)用for in 枚舉循環(huán)
Obj每個實例都具有屬性和方法
Constructor: 保存著用于創(chuàng)建當(dāng)前對象的函數(shù)。(構(gòu)造函數(shù))
hasOwnProperty(propertyName):用于檢測給定的屬性在當(dāng)前對象實例中(而不是原型中)是否存在。
isPrototypeOf(Object): 用于檢查傳入的對象是否是另外一個對象的原型。
propertyIsEnumerable(propertyName):用于檢查給定的屬性是否能夠使用for-in語句來枚舉。
toLocaleString():返回對象的字符串表示。該字符串與執(zhí)行環(huán)境的地區(qū)對應(yīng).
toString():返回對象的字符串表示。
valueOf():返回對象的字符串、數(shù)值或布爾表示。
OBject.prototype.toString()
Object.prototype.toString
作用:根據(jù)內(nèi)部的this返回一個類似于這樣的字符串 [object constructorName]
這個方法有個缺點,不能獲取用戶自定義對象的具體類型.
只能獲取內(nèi)置對象的類型.
自定義對象類型都返回:[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
// 數(shù)組 ==> Array.prototype.toString();
var b = [1, 2, 3, 4];
console.log(b.toString()); // 1,2,3,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]
// 函數(shù)
console.log(Function.toString()); // function Function() { [native code] }
console.log(Array.toString()); // function Array() { [native code] }
console.log(RegExp.toString()); // function RegExp() { [navtive code] }
關(guān)于JSON函數(shù)
JSON.parse()
作用:將JSON字符串解析成JavaScirpt值。在解析過程中,可以選擇性的修改某些屬性的原始解析值。
參數(shù)1:JSON字符串
參數(shù)2: reviver 函數(shù),用來轉(zhuǎn)換解析出的屬性值。(可選參數(shù))
返回值:解析出的一個 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 函數(shù),解析的出的Object, 解析值本身以及它所包含的所有屬性,會按照一定的順序(從最最里層的屬性開始,一級級往外,最終到達(dá)頂層)分別去調(diào)用 指定的reviver 函數(shù)。
在調(diào)用過程中,當(dāng)前屬性所屬的對象會作為this值,當(dāng)前屬性名和屬性值會分別作為第一個參數(shù)和第二個參數(shù)傳入 reviver 函數(shù)中,如果 reviver 函數(shù)返回undefeind,則當(dāng)前屬性會從屬性對象中刪除,如果返回了其它值,則返回的值會成為當(dāng)前屬性新的屬性值。
當(dāng)遍歷到最頂層的值(解析值)時,傳入reviver函數(shù)的參數(shù)會是空字符串''(因為此時已經(jīng)沒有真正的屬性)和當(dāng)前的解析值(有可能已經(jīng)被修改過),當(dāng)前的this值會是{"":修改過的解析值},
JSON.parse('{"p": 5}', function (key, val) {
if(key === '') return val; // 如果到了最頂層,則直接返回屬性值
return val * 2;
});
JSON.stringify();
stringify(value [,replacer, [space]]);
將任意的JavaScript值序列化成JSON字符
參數(shù)1:value: 將序列化成JSON字符串的值
參數(shù)2:replacer: 可選,如果是一個函數(shù),則在序列化過程中,被序列化的值的每個屬性都會經(jīng)過該函數(shù)的轉(zhuǎn)換和處理。 如果是一個數(shù)組,則暴行在這數(shù)組中的屬性名才會被序列化到最終的JSON字符串中。
參數(shù)3:space, 指定縮進(jìn)可通的空白字符串,用于美化輸出。 控制結(jié)果字符串里的間距。
注意:
-
不可枚舉的屬性會被忽略
-
非數(shù)組對象的屬性不能保證以特定的順序出現(xiàn)的序列化后的字符串中。
-
布爾值,數(shù)字,字符串的包裝對象在序列化過程中會自動裝換成對應(yīng)的原始值。
-
undefeind,任意的函數(shù),以及symbol值,在徐淚花過程橫縱揮別忽略(出現(xiàn)在非數(shù)組對象的屬性值中時)或者被轉(zhuǎn)換成null(出現(xiàn)在數(shù)組中時)
-
所有以symbol為屬性鍵的屬性值都會被完全忽略掉,即便 replacer參數(shù)中強制指定包含了它們
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();
作用:創(chuàng)建一個類,是一種寄生式繼承。
返回一個類,這個類的原型指向傳遞進(jìn)來的對象。
創(chuàng)建的實例化對象,構(gòu)造函數(shù)指向的是繼承的對象的類的構(gòu)造函數(shù)。本身沒有原型,可以通過原型鏈找到繼承的對象類中的原型。具有繼承對象上的屬性以及方法。
因此,創(chuàng)建的實例化對象可以使用繼承對象上的屬性和方法。
var Book = function (title, price) {
this.title = title;
this.price = price;
}
Book.prototype.sayTitle = function () {
return this.price;
}
var book = new Book('one', 10);
// 創(chuàng)建一個繼承類
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
}
}
// 創(chuàng)建一個繼承類
var NewBook = Object.create(book);
console.log(NewBook.constructor);
var price = NewBook.sayTitle();
console.log(price);
Object.defineProperty
Object.defineProperty();
直接在一個對象上定義一個新屬性,或者修改一個已經(jīng)存在的屬性,并返回這個對象。
參數(shù)1:需要被設(shè)置的對象
參數(shù)2:設(shè)置的屬性名
參數(shù)3:配置項,添加屬性的特性屬性
特性屬性:
value:該屬性值,默認(rèn)值:undefeind
writable: 可否被修改,默認(rèn)值:false (不能被修改)
configuarable: 能否通過delete刪除屬性從而重新定義屬性,能夠修改屬性的特性,或者能否把屬性修改為訪問屬性。 默認(rèn)值:false;(不可以重新定義或刪除)
enumerable: 是否可以被for-in枚舉。默認(rèn)值: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。默認(rèn)值undefiend。
參數(shù):該參數(shù)的新值分配給該屬性。默認(rèn):undefined
Object.defineProperty(obj, 'title', {
get: function () {
console.log('get');
return this._title;
},
set: function ( val ) {
this._title = val;
}
});
obj.title = 'pink';
var t = obj.title;
defineProperties
在一個對象上添加或修改一個或多個自有屬性,并返回該對象。
參數(shù)1:表示要被處理的對象
參數(shù)2:定義多個屬性特性對象
var obj = {}
Object.defineProperties(obj, {
color: {
value: 'tan'
},
names: {
value: 'zf'
}
});
console.log( obj );
getOwnPropertyNames
Object.getOwnPropertyNames();
返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性)組成的數(shù)組。
參數(shù):需要獲取的對象。
getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor();
指定對象上一個自由屬性對應(yīng)的屬性描述符。(自由屬性指的直接賦予該對象的屬性,不需要從原型鏈上進(jìn)行查找的屬性)
參數(shù)1: 獲取的對象。
參數(shù)2:獲取的屬性值
模擬map
模擬java中的Map
//簡單實現(xiàn) map
function Map () {
//priveate 的對象來保存 key 和 val
var obj = {};
// put 方法
this.put = function ( key,val ) {
obj[key] = val; //把鍵值對 綁定到object上.
}
//獲得map 容器的個數(shù)
this.size = function () {
var count = 0;
for ( var i in obj ) {
count++;
}
return count;
}
//根據(jù)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,i,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,'---' );
});
去掉數(shù)組的重復(fù)項
var arr = [1,2,4,2,3,4,5,546,57,6,5,4,31,57];
//js 對象特性, 數(shù)組去重
// 在 js 對象 中 key 是永遠(yuǎn) 不會重復(fù)的.
// 1, 把數(shù)組轉(zhuǎn)成一個js的對象
// 2,把數(shù)組中的值,變成js 對象當(dāng)中的key
// 3,把對象再還原成數(shù)組
//數(shù)組轉(zhuǎn)對象
var toObject = function ( arr ) {
var reslutObj = {};
for ( var i=0; i<arr.length; i++ ) {
if ( arr ) {
reslutObj[arr[i]] = null; //賦值為任意值
}
}
return reslutObj;
}
//對象轉(zhuǎn)成數(shù)組
var toArray = function ( obj ) {
var reslutArr = [];
for ( var attr in obj ) {
if ( obj.hasOwnProperty(attr) ) { //判斷是否是自身上面的屬性
reslutArr.push(attr);
}
}
return reslutArr;
}
//去掉數(shù)組中的重復(fù)項
function uniq ( arr ) {
return toArray(toObject(arr));
}
console.log( uniq(arr) );
其他引用類型
單體對象(不需要實例化對象,就可以使用的方法):
Global對象(全局)這個對象不存在,無形的對象(特別的,特殊的存在)
其內(nèi)部定義了一些方法和屬性: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: //不會進(jìn)行編碼) var str2 = encodeURIComponent(uri); //http%3A%2F%2Fwww.baidu.com%20cn //任何不標(biāo)準(zhǔn)的文字都會進(jìn)行編碼 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 );
//數(shù)組字符串 直接使用: eval(strArr);
var arr = '[10,203,345,45,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 轉(zhuǎn)碼 var str = '八百米'; var str2 = escape(str); //%u516B%u767E%u7C73 console.log( str2 );
Math對象
內(nèi)置的Math對象可以用來處理各種數(shù)學(xué)運算
可以直接調(diào)用的方法:Math.數(shù)學(xué)函數(shù)(參數(shù))
求隨機數(shù)方法:Math.random(),產(chǎn)生 [0,1) 范圍一個任意數(shù)
Date對象
獲取當(dāng)前時間的一系列詳細(xì)方法
var date = new Date(); console.log( date.getTime() ); //當(dāng)前時間的毫秒數(shù)
基本包裝類型:Boolean、String、Number
Function類型、RegExp類型
簡單單體和閉包單體
單體(singleton)模式是js中最基本但又最有用的模式之一,它可能比其他任何模式都常用。
這種模式提供了一種將代碼組織為一個邏輯單元的手段,這個邏輯單元中的代碼可以通過單一的變量進(jìn)行訪問。通過確保單體對象只存在一份實例,就可以確信自己的所有代碼使用的都是同樣的全局資源。
簡單單體
// 簡單單體模式 (只能創(chuàng)建一個實例)//無法通過new 關(guān)鍵字來實例化.
var Singleton = { //當(dāng)成模板類
attr1: true,
attr2: 10,
method1: function () {
console.log( this.attr1 );
}
}
Singleton.method1();
//劃分命名空間(區(qū)分代碼)
閉包單體
// 利用閉包來創(chuàng)建單體 , 閉包主要的目的 , 保護(hù)數(shù)據(jù)
var alogy = {};
alogy.singleton = (function () {
//添加私有成員
var a = 100;
var fn1 = function () {
console.log( a );
}
// 塊級作用域里的執(zhí)行結(jié)果賦值 單體對象
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;
//需要一個構(gòu)造器 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 ) { //不存在 ,創(chuàng)建單體實例
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
簡單鏈?zhǔn)骄幊虒崿F(xiàn)
簡單鏈?zhǔn)秸{(diào)用。 return this;
//簡單函數(shù)鏈?zhǔn)秸{(diào)用
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底層鏈?zhǔn)骄幊?
// 函數(shù)自執(zhí)行 特點:
// 1: 程序啟動時候 里面代碼自動執(zhí)行
// 2: 內(nèi)部的成員變量 外部無法訪問 (除了不加var修飾的變量)
//塊級 作用域
(function ( window,undefined ) {
//$ 最常用的對象 返回給外界 //大型程序開發(fā) 一般使用 '_'作為私有的對象
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類上 擴展 一個可以實現(xiàn) 鏈?zhǔn)骄幊痰姆椒?
Function.prototype.method = function ( methodName,fn ) { //實現(xiàn)鏈?zhǔn)骄幊蹋?方法的名字 和 進(jìn)行調(diào)用的函數(shù)是什么
this.prototype[methodName] = fn;
return this; //鏈?zhǔn)骄幊?
}
// 在 _$ 原型對象上 加一些公共的方法
_$.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.$ = _$;
//準(zhǔn)備方法
_$.onReady = function ( cb ) {
//1,實例化 _$ 對象 ,注冊到 window上
window.$ = function ( args ) {
return new _$(args);
}
//2: 執(zhí)行傳入的代碼
cb.call(window);
//3: 實現(xiàn)鏈?zhǔn)骄幊?
_$.method('addEvent',function () {}).method('setStyle',function () {});
}
})( window ) //程序的入口 window傳入作用域中
$.onReady(function () {
$('#div')
.addEvent('click',function () {
console.log('點擊了');
})
.setStyle('background','pink')
});
嚴(yán)格模式
嚴(yán)格模式是JavaScript中的一種限制性更強的變種方式。
嚴(yán)格模式與非嚴(yán)格模式可以共存,可以逐漸的選擇性加入嚴(yán)格模式。
全局作用域
定義變量必須通過var。
嚴(yán)格模式禁止刪除聲明變量。
delete關(guān)鍵字
使用delete刪除一個變量名(而不是屬性名): delete myVariable
'use strict'; delete Object.prototype; // error . // 刪除一個不可配置的屬性
函數(shù)參數(shù)
定義相同名稱的參數(shù)
要求參數(shù)名唯一。
在正常模式下,最后一個重名參數(shù)名諱覆蓋之前的重名參數(shù),之前的參數(shù)仍然可以通過arguments[i]來訪問,還不是完全無法訪問。
關(guān)鍵字,保留字
使用eval或arguments作為變量名或函數(shù)名
嚴(yán)格模式下:
訪問arguments.callee, arguments.caller, anyFunction.caller以及anyFunction.arguments都會拋出異常
禁止使用八進(jìn)制
瀏覽器都支持以零(0)開頭的八進(jìn)制語法:0644 == 420 還有 '\045 === '%''
認(rèn)為數(shù)字的前導(dǎo)零沒有語法意義,但是會改變數(shù)字的意義。
eval
嚴(yán)格模式下不能向全局作用域下添加變量
在正常模式下,代碼eval('var x;') 會給上層函數(shù)或全局引入一個新的變量 x
嚴(yán)格模式下,eval為被運行的代碼創(chuàng)建變量,eval不會影響到名稱映射到外部變量或其它局部變量。
var x = 22;
var evalX = eval("var x = 42; x");
console.log(x === 22);
console.log(evalX === 42);
函數(shù)內(nèi)部this
在正常模式下函數(shù)調(diào)用,this的值會指向全局對象,在嚴(yán)格模式中,this的值會指向undefiend。
當(dāng)函數(shù)通過call和apply調(diào)用時,如果傳入的是thisvalue參數(shù)是一個null和undefiend除外的原始值(字符串,數(shù)字,布爾值),則this的值會成為那個原始值的對應(yīng)的包裝對象。如果thisavlue參數(shù)的值是undefeind或null,則this的值會指向全局變量。在嚴(yán)格模式中,this值就是thisvalue參數(shù)的值,沒有任何類型轉(zhuǎn)換。
this: 僅在this指向自己創(chuàng)建的對象時使用它
arguments
arguments對象屬性不語對應(yīng)的形參變量同步更新。
非嚴(yán)格模式下,修改arugmetns對象中的某個索引屬性的值,和這個屬性對應(yīng)的形參變量的值也會同時變化。
嚴(yán)格模式下,arguments對象會以形參變量的拷貝的形式被創(chuàng)建和初始化。因此arguments對象的改變不會影響形參。
arguments: 總是通過形參的名字獲取函數(shù)參數(shù),或者在函數(shù)的第一行拷貝arguments
var args = Array.prototype.slice.call(arguments)
with
嚴(yán)格模式禁用with。
with問題:塊內(nèi)的任何變量都可以映射到with傳進(jìn)來的對象的屬性,也可以映射到包圍這個塊的作用域內(nèi)的變量(甚至是全局變量),在運行時才能夠決定:在代碼運行之前無法得到。
嚴(yán)格模式下,使用with會引起語法錯誤。
var x = 7;
with (obj) { // 語法錯誤
// 如果沒有開啟嚴(yán)格模式,with中的這個x會指向with上面的那個x,還是obj.x?
// 如果不運行代碼,我們無法知道,因此,這種代碼讓引擎無法進(jìn)行優(yōu)化,速度也就會變慢。
x;
}
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
相關(guān)文章
JS面試必備之手寫instanceof,深拷貝,節(jié)流和防抖
JavaScript如何實現(xiàn)手寫instanceof、深拷貝、節(jié)流、防抖也是面試時常??嫉降闹R點,這篇文章為大家進(jìn)行了詳細(xì)介紹,需要的可以參考一下2023-05-05
利用BootStrap的Carousel.js實現(xiàn)輪播圖動畫效果
這篇文章主要介紹了利用BootStrap的Carousel.js實現(xiàn)輪播圖動畫效果的相關(guān)資料,需要的朋友可以參考下2016-12-12
JavaScript中click和onclick本質(zhì)區(qū)別與用法分析
這篇文章主要介紹了JavaScript中click和onclick本質(zhì)區(qū)別與用法,結(jié)合實例形式分析了JavaScript中click和onclick的具體概念、功能、使用場景及相關(guān)操作技巧,需要的朋友可以參考下2018-06-06
IE8的JavaScript點擊事件(onclick)不兼容的解決方法
這篇文章主要介紹了IE8的JavaScript點擊事件(onclick)不兼容的解決方法,大家參考使用吧2013-11-11

