js笔记(三)ES5、ES5新增的数组的方法、字符串的方法、字符编码、对象的序列化和反序列化、bind
數組方法、字符串方法總結
| 一、ES5嚴格模式 | 1. 嚴格模式; 2. 嚴格模式的行為變更; |
| 二、ES5新增的數組的方法 | 1. 判斷是否為數組:Array.isArray(); 2. 判斷數組中是否存在某個值:indexOf(data, start)、lastIndexOf(); 3. ES5新增的遍歷數組的方法forEach()、map()、filter()、some()、every(); |
| 三、字符串的方法(偏ES5) | 1.判斷字符串中是否存在某個字符:indexOf()、lastIndexOf(); 2. 返回在指定位置的字符或字符編碼:charAt(index)、charCodeAt(); 3. 截取:slice()、substr()、substring(); 4. 字符大小寫轉換:toLowerCase()、toUpperCase(); 5. 字符中有關正則的方法:match()、replace()、search(); 6. 字符轉成數組:split();; 7. 合并字符串:concat(); 8. 去除字符串守衛的空格:trim(); |
| 四、字符編碼 | 1. ASCII; 2. Unicode編碼; 3. GBk; |
| 五、ES5對象的序列化和反序列化 | 1. json 轉字符: JSON.stringify(str); 且轉換后是嚴格寫法的 json 格式字符串; 2. 字符轉 json: JSON.parse(str); 要求 str 必須是一個嚴格寫法的 json 格式字符串。否則會報錯; |
| 六、ES5函數的方法:bind | 1. bind 的作用; 2. 利用 bind 封裝事件委托; 3. apply 查找數組中的最小/大值; 4. bind/call/apply 的區別 |
一、ES5嚴格模式
ie(IE10+)低版本不支持嚴格模式( js 代碼還是能夠兼容,只是說不支持嚴格模式而已)
1.1 嚴格模式
(1)調用嚴格模式:
① 全局調用:在要開啟嚴格模式的代碼的作用域的第一行添加:"use strict";
② 局部調用:
function fn(){"use strict";//... }③ 匿名函數開啟嚴格模式:(前后都要加 “;” )
;(function(){"use strict"; })();(2)作用:
① 消除了 js 語法的一些不合理、不嚴謹支出,減少一些怪異
② 消除了代碼運行的一些不安全之處,保證代碼運行的安全;
③ 提高編譯器的效率,增加運行速度;
④ 為未來新版本的 js 做好鋪墊;
1.2 嚴格模式的行為變更
嚴格模式的行為變更:
(1)全局變量聲明時,必須使用關鍵字 var;
(2)函數內不允許出現重復名參數;
(3)全局函數中的 this不再指向 window,指向 undefined ;
(4)arguments對象不允許被動態改變;
(5)嚴格模式下不允許使用 argument.callee;
(6)新增保留字: implements、interface、let、package、private、protected、public、static、yield;
(1)全局變量聲明時,必須使用關鍵字 var;
a = 10; console.log(a);//10"use strict"; a = 10; console.log(a);//Uncaught ReferenceError: a is not defined(2)函數內不允許出現重復名參數;
function fn(a,b,b){console.log(a);//1console.log(b);//3 } fn(1,2,3);"use strict"; function fn(a,b,b){console.log(a);//1console.log(b);//報錯 } fn(1,2,3);(3)全局函數中的 this不再指向 window,指向 undefined ;
function fn(){console.log(this);//指向 window } fn();"use strict"; function fn(){console.log(this);//指向 undefined } fn(); //window.fn();//此時的this指向window(4)arguments對象不允許被動態改變;
function fn(a){a = 10;console.log(a);//10console.log(arguments);//10 } fn(4);"use strict"; function fn(a){a = 10;console.log(a);//10console.log(arguments);//4 } fn(4);(5)嚴格模式下不允許使用 argument.callee;
"use strict"; function fn(n){if(n == 1){return 1;} else {//return n*fn(n-1);//或者return n*arguments.callee(n-1);} } console.log(fn(4));//24 //嚴格模式下報錯:Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them(6)新增保留字: implements、interface、let、package、private、protected、public、static、yield;
二、ES5新增的數組的方法
2.1 判斷是否為數組:Array.isArray();
結果返回布爾值,數組返回true,非數組返回false。typeof()無法區分數組和對象,此方法可以 。
var arr = [1,3,5]; var obj = {name:"a",age:18}; console.log( Array.isArray(arr) ); //true console.log( Array.isArray(obj) ); //false console.log( typeof(arr) ); //object console.log( typeof(obj) ); //object2.2 判斷數組中是否存在某個值:indexOf(data, start)、lastIndexOf()
(1)indexOf(data, start),返回要查找數值在數組中的索引,若沒有就是 -1;
var arr = [3,5,6,9,8,2]; console.log(arr.indexOf(5)); //1 console.log(arr.indexOf(91));//-1//start 為開始位置,從start開始遍歷,返回它在數組中總的位置 var arr = [5,3,5,6,8,5,2]; console.log(arr.indexOf(5,4));//5 console.log(arr.indexOf(5,6));//-1- 數組去重:var arr = [3,5,6,2,1,8,5,4,2,"2"];var newArr = []; for(var i = 0;i<arr.length; i++){if(newArr.indexOf(arr[i]) == -1){newArr.push(arr[i]);} } console.log(newArr);//(8) [3, 5, 6, 2, 1, 8, 4, "2"]
(2)lastIndexOf(),從后面往前找,但索引值不變(沒有就返回 -1);
var arr = [2, 5, 4, 8, "2", "4", 2, 6, 12, 2, 4]; console.log(arr.lastIndexOf(2)); //9 console.log(arr.lastIndexOf("3"));//-12.3 ES5新增的遍歷數組的方法forEach()、map()、filter()、some()、every()
(1)forEach( function(val, index, arr){ }),專門用來 遍歷數組;
var arr = [8,7,5,7,4,6]; arr.forEach(function(val,index,arr){console.log(val);//8 7 5 7 4 6console.log(index);//0 1 2 3 4 5console.log(arr);//(6) [8, 7, 5, 7, 4, 6] })(2)map( function(val, index, arr){ }),返回原數組長度的數組 ;
不僅可以實現 forEach 的遍歷,還可以有返回值。常用 map() + return來修改原數組的值,返回一個新數組,不影響原數組。
var arr = [8,7,5,7,4,6]; //1. 沒有 return 時,效果與forEach相同 arr.map(function(val,index,arr){console.log(val);//8 7 5 7 4 6console.log(index);//0 1 2 3 4 5console.log(arr);//(6) [8, 7, 5, 7, 4, 6] })//2. map() 中使用 return 的用法 var a = arr.map(function(val,index,arr){return "hello"; }) console.log(a);//(6) ["hello", "hello", "hello", "hello", "hello", "hello"]//3. 在map()中使用return,map()可以修改原數組的值,但不會影響到原數組 var b = arr.map(function(val,index,arr){return val+10; }) console.log(b);//(6) [18, 17, 15, 17, 14, 16] console.log(arr);//(6) [8, 7, 5, 7, 4, 6](3)filter( function(val, index, arr){ }),過濾,不改變原數組。
將函數執行一遍,只有在 布爾值為 true 時才返回符合條件的 數據。效果與 map() 類似。
var arr = [8,7,5,7,4,5,6]; //沒有 return 時,效果與forEach相同 arr.filter(function (val, index, arr){console.log(val);//8 7 5 7 4 5 6console.log(index);//0 1 2 3 4 5 6console.log(arr);//(7) [8, 7, 5, 7, 4, 5, 6] })//2. filter() 中 return 的是一個布爾值,過濾出條件為 true 的值 var b = arr.filter( function(val, index,arr){return "hello";//字符為true,空字符為false }) console.log(b);//(7) [8, 7, 5, 7, 4, 5, 6]//3. 過濾出符合條件的數據 var a = arr.filter( function (val ,index, arr){return val > 6; }) console.log(a); //(3) [8, 7, 7](4)some( function(val){ }),判斷數組是否存在某個屬性值/對象(indexOf()有局限性);
indexOf()有局限性,遍歷數組時,如果數組中某條數據符合判斷條件,則返回值為 ture。
(5)every( function(val){ }),遍歷數組時,每條數據都滿足判斷條件時,返回 ture,只要有一條不滿足則返回false。IE瀏覽器不支持。
var arr = [{name: "lili", age: 18},{name: "hxl", age: 19} ]; var res = arr.some(function(item){console.log(item);//打印結果:{name: "lili", age: 18} // {name: "hxl", age: 19}return item.age === '18'; //判斷條件 }); console.log(res); //false 有一條數據不滿足條件三、字符串的方法(偏ES5)
字符串可以是插入到引號中的任何字符。你可以使用單引號或雙引號。
創建字符串的方式:
(1)字面量方式創建:var str = "hello";;
(2)構造函數方式創建:var str = new String("hello");
字符串像數組一樣也有長度,意味著它可以像數組一樣通過索引來獲取字符。
var str = "I love you"; console.log(str.length); //10 conosle.log(str[0]); //I3.1 判斷字符串中是否存在某個字符:indexOf()、lastIndexOf()
indexOf(data, start),lastIndexOf(data, start)用法與在數組中一樣。字符在字符串中存在返回索引,不存在就返回 -1。
var str = "hello world"; console.log( str.indexOf("o") ); //4 console.log( str.lastIndexOf("o") ); //73.2 返回在指定位置的字符或字符編碼:charAt(index)、charCodeAt()
(1)charAt(index),返回在指定位置的字符;
var str = "hello world"; console.log(str.charAt(10));//d(2)charCodeAt(),返回指定的位置的字符的 Unicode 編碼;
var str="abc"console.log(str.charCodeAt(1))//98,98是b的十進制編碼3.3 截取:slice()、substr()、substring();
(1)slice(start, end),截取從 start 到 end 位置的字符串,含前不含后; 返回新的字符串,不會改變原字符串。slice() 更多用于數組。
- start,必須值(數值形式),字符串的起始下標,若是負值就會從字符串末尾開始算,從 -1 開始。
- end,可選,截取到字符串的 end 位置。如果不寫,就會截取到 start 位置-字符串末尾。
(2)substr(start, length),從 start 位置開始截取(包括 start 位置的字符),截取長度為 length 的字符串出來。返回新的字符串,不會改變原字符串。
- start,必須值(數值形式),字符串的起始下標,若是負值就會從字符串末尾開始算,從 -1 開始。
- length,可選,截取到的字符串的長度。如果不寫,就會截取到 start 位置-字符串末尾。
(3)substring(start, end),截取從 start 到 end 位置的字符串,含前不含后;返回新的字符串,不會改變原字符串。與 slice() 作用和用法相同。
var str = "hello world"; console.log(str.substring(2)); //llo world console.log(str.substring(2,8)); //llo wo console.log(str); //hello world3.4 字符大小寫轉換:toLowerCase()、toUpperCase()
(1)toLowerCase(),把字符串轉換為小寫;
var str = "Hello ShangHai!I love YOU."; console.log(str.toLowerCase()); //hello shanghai!i love you.(2)toUpperCase(),把字符串轉換為大寫;
var str = "Hello ShangHai!I love YOU."; console.log(str.toUpperCase()); //HELLO SHANGHAI!I LOVE YOU.3.5 字符中有關正則的方法:match()、replace()、search()
(1)match(),在字符串內檢索指定的值(類似indexOf(),不過返回的是值而非索引),或找到一個或多個正則表達式的匹配。
var str="1 abc 2 def 3" console.log(str.match(/\d+/g)); //123(2)replace(oldval, newVal),替換(一次只能替換一個)
var str = "hello world"; console.log(str.replace("o","啊"));//hell啊 world- 若想替換多個//方法1 var str = "hello world"; console.log(str.replace("o","啊").replace("o","啊"));//hell啊 w啊rld//方法二 for(var i = 0; i< str.length; i++){str = str.replace("o","哦"); } console.log(str);//hell哦 w哦rld
- 敏感詞過濾(上面這種方法耗內存,最好用正則)var msg = ['fuck',"滾",'tm','nnd','sb','sx'];//敏感詞庫 var str = "你tm真讓人無語";//要說的話 for(var i=0;i<str.length;i++){msg.forEach( function (val,index){str = str.replace(val,"**");}) } console.log(str);//你**真讓人無語
(3)search(),返回指定字符串的索引,如果沒有就返回 -1。
var str="abc DEF!" console.log(str.search(/DEF/))//43.6 字符轉成數組:split();
var str = "2018/7/30"; console.log(str.split());//["2018/7/30"] console.log(str.split(""));//(9) ["2", "0", "1", "8", "/", "7", "/", "3", "0"] console.log(str.split("/"));//(3) ["2018", "7", "30"]3.7 合并字符串:concat();
var a = "abc"; var b ="def"; console.log(a.concat(b));//abcdef3.8 去除字符串首尾的空格:trim()
var str = ' 555 666 '; console.log(str.trim()); //555 666四、字符編碼
計算機中儲存的信息都是用二進制數表示的;我們在屏幕上看到的英文、漢字等字符是二進制數轉換之后的結果。
- 按照何種規則將字符存儲在計算機中,如’a’用什么表示,稱為"編碼";反之,將存儲在計算機中的二進制數解析顯示出來,稱為"解碼",同密碼學中的加密和解密。
- 在解碼過程中,如果使用了錯誤的解碼規則,則導致’a’解析成’b’或者亂碼。
- 字符集(Charset):是一個系統支持的所有抽象字符的集合。字符是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。
- 字符編碼(Character Encoding):是一套法則,使用該法則能夠對自然語言的字符的一個集合(如字母表或音節表),與其他東西的一個集合(如號碼或電脈沖)進行配對。即在符號集合與數字系統之間建立對應關系,它是信息處理的一項基本技術。
常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。
charCodeAt();,字符轉ASCII碼(十進制),中文轉十進制;
charCodeAt(n);,返回指定位置的字符的Unicode;
String.fromCharCode(n) ,
- n 為 ASCII碼,ASCII碼 轉 字符;
- n 為 十進制,十進制 轉 中文;
- n 為 十六進制,十六進制 轉 中文;
4.1 ASCII:
ASCII:美國信息交換標準碼,主要用于顯示現代英語。
ASCII字符集:主要包括控制字符(回車鍵、退格、換行鍵等);可顯示字符(英文大小寫字符、阿拉伯數字和西文符號)。
ASCII編碼:將 ASCII字符集 轉換為計算機可以接受的數字系統的數的規則。
(1)字符轉ASCII碼(十進制):charCodeAt();
(2)ASCII碼 轉 字符: String.fromCharCode(ASCII碼)
4.2 Unicode編碼:
萬國碼、統一碼、單一碼。將世界上所有的符號都納入其中,無論是英文、日文、還是中文等,大家都使用這個編碼表,就不會出現編碼不匹配現象。
可以這樣理解:Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三種字符編碼方案。
(1)中文轉十進制: charCodeAt();
(2)十進制轉中文:String.fromCharCode(十進制);
(3)十六進制轉中文: String.fromCharCode('0x十六進制');
(4)返回指定位置的字符的Unicode: charCodeAt(n);
UTF-8:只有網頁上使用。
4.3 GBK:只有中文
五、ES5對象的序列化和反序列化
1. json 轉字符: JSON.stringify(str); 且轉換后是嚴格寫法的 json 格式字符串;
2. 字符轉 json: JSON.parse(str); 要求 str 必須是一個嚴格寫法的 json 格式字符串。否則會報錯;
- 注意: cookie 存值的時候,值最好是字符,若是對象,會被轉換成 [object Object]。所以要存對象時,首先要把它變成字符串格式。
六、ES5函數的方法:bind
ES5函數的方法:bind
作用:
(1)改變原函數的 this 的指向,指向 bind 中的第一個參數;
(2)bind 也是函數的方法。可以讓原本沒有某個功能的對象,具有這個功能。
bind 返回的是一個新的函數,你必須調用它才會被執行。
(3)bind 的第二個參數往后所有參數,會當成原函數的參數,把原函數擠到后面,并和原本的參數一起被存到arguments中。
6.1 bind 的作用
(1)改變原函數的 this 的指向,指向 bind 中的第一個參數** ,并且把指向的內容強行修改為對象。
var obj = {name:"admin",show:function(){document.onclick = function(){console.log(this);}.bind(obj);} } obj.show(); //也可以將bind寫在調用方法的后面 obj.show.bind(obj)(); //原本指向 document,打印: #document //.bind(obj)后this指向 obj,打印: {name: "admin", show: ?}把指向的內容強行修改為對象。
var obj = {name:"admin",show:function(){document.onclick = function(){console.log(this);}.bind("hello");} } obj.show(); //String {"hello"}(2)bind 也是函數的方法。可以讓原本沒有某個功能的對象,具有這個功能。
var a = {name : "小明",show: function(){console.log(this.name+"在踢球");} } var b = {name: "小黃" } a.show();//小明在踢球 a.show.bind(b)();//小黃在踢球 //a.show().bind(b)//小明在踢球 a.show()就已經執行了a中的函數show a.show().bind(b)();//報錯(3)bind 的第二個參數往后所有參數,會當成原函數的參數,把原函數中的參數往后面擠,多下來的參數和原本的參數一起被存到 arguments 中。
var obj = {name: 'admin',show: function(a,b){console.log(a,b);console.log(arguments);console.log(this);} } obj.show.bind("hello")("10",20); obj.show.bind("hello","world")("10",20); obj.show.bind("hello","world","js")("10",20);
6.2 利用 bind 封裝事件委托
原來的事件委托 this 指向的父元素(用 target),利用 bind 改為操作哪個元素,this 就指向這個元素。
//使用: 父元素.onclick = eveEntrust(子元素,function(){//操作}) oul.onclick = eveEntrust("LI",function(){console.log(this); })function eveEntrust(child,callback){return function(eve){var e = eve || winodw.event;var target = e.target || e.srcElement;if(target.nodeName == child){//callback(target);//此時的this指向window;若用這種方法,則使用時函數要含參數來接收這個 targetcallback.bind(target)();}} }- 最終版:varali = oul.children; //使用: 父元素.onclick = eveEntrust(所有子元素DOM,function(){//操作}) oul.onclick = eveEnt(ali,function(){console.log(this) })function eveEnt(child,callback){return function(eve){var e = eve || window.event;var target = e.target || e.srcElemt;for(var i=0; i<child.length; i++){if(target == child[i]){callback.bind(target)();}}} }
6.3 apply 查找數組中的最小/大值
當min接收多個參數時,在min函數內部,肯定要對這些參數進行處理和比較。當傳數組時,只有一個數據,沒辦法對數組內部的數據逐個比較,所以 Math.min(arr) 的返回結果是NaN。
var arr = [23,45,74,73,42,65,78]; var min = Math.min.apply(null, arr); console.log(min); //23- 按照前面介紹的,數組 arr 作為參數被 Math.min 的方法解析,其實就相當于Math.min.call(null, 23,45,74,73,42,65,78);
- null 作為第一個參數,是用來改變 this指向,傳 null 或 undefined 時,將是JS執行環境的全局變量。
6.4 bind、call、apply的區別
| 1 | 都是用來改變函數的 this 對象的指向的。 |
| 2 | 第一個參數都是 this 要指向的對象。 |
| 3 | 都可以利用后續參數傳參。 |
| 4 | 三者的參數不限定是 string 類型,允許是各種類型,包括函數 、 object 等。 |
三者的不同:
(1)bind 返回的是一個新的函數,必須調要用它才會被執行。
(2)call 的參數是直接放進去的,第二第三第 n 個參數全都用逗號分隔,直接放到后面 對象中的方法.call(this指向,'參數1', ... ,'參數n' )。bind 除了返回是函數以外,它的參數和 call 一樣。
(3)apply 的所有參數都必須放在一個數組里面傳進去 對象中的方法.apply(this指向,['參數1', ... ,'參數n'])。
一個參數:
var a = {name : "小明",show: function(){console.log(this.name+"在踢球");} } var b = {name: "小黃" } a.show.bind(b)();//小黃在踢球 a.show.call(b);//小黃在踢球 a.show.apply(b);//小黃在踢球多個參數:
var a = {name : "小明",age: "18",show: function(from,to){console.log(this.name+"的年齡是:"+this.age+",來自:"+from+",要去往:"+to);} } var b = {name: "小黃",age: "19", } a.show.bind(b,"成都","上海")(); //小黃的年齡是:19,來自:成都,要去往:上海 a.show.bind(b)("成都","上海"); //小黃的年齡是:19,來自:成都,要去往:上海 a.show.bind(b,"成都")("上海"); //小黃的年齡是:19,來自:成都,要去往:上海a.show.call(b,"成都","上海"); //小黃的年齡是:19,來自:成都,要去往:上海 a.show.apply(b,["成都","上海"]); //小黃的年齡是:19,來自:成都,要去往:上海上一篇——js(一)js基礎、程序結構、函數、對象和構造函數、數組、this
下一篇——js(三)事件、cookie、正則、ES6
總結
以上是生活随笔為你收集整理的js笔记(三)ES5、ES5新增的数组的方法、字符串的方法、字符编码、对象的序列化和反序列化、bind的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js笔记(一)js基础、程序结构、函数
- 下一篇: js笔记(六)事件、正则