数组方法、字符串方法总结
大目录 | 小目录 |
---|---|
一、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) ); //object
2.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"));//-1
2.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
。
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.name === 'hxl'; //判断条件
});
console.log(res); //true 存在hxl
(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]); //I
3.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") ); //7
3.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 位置-字符串末尾。
var str = "hello world";
console.log(str.slice(2,7));//llo w
(2)substr(start, length)
,从 start 位置开始截取(包括 start 位置的字符),截取长度为 length 的字符串出来。返回新的字符串,不会改变原字符串。
start
,必须值(数值形式),字符串的起始下标,若是负值就会从字符串末尾开始算,从-1
开始。length
,可选,截取到的字符串的长度。如果不写,就会截取到 start 位置-字符串末尾。
var str = "hello world";
console.log(str.substr(2)); //llo world
console.log(str.substr(1,6)); //ello w
console.log(str); //hello world
(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 world
3.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/))//4
3.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));//abcdef
3.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码)
console.log('0'.charCodeAt());//48
console.log('1'.charCodeAt());//57
console.log('A'.charCodeAt());//65
console.log('a'.charCodeAt());//97console.log(String.fromCharCode(97));//a
4.2 Unicode编码:
万国码、统一码、单一码。将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。
可以这样理解:Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三种字符编码方案。
(1)中文转十进制: charCodeAt();
(2)十进制转中文:String.fromCharCode(十进制);
(3)十六进制转中文: String.fromCharCode('0x十六进制');
(4)返回指定位置的字符的Unicode: charCodeAt(n);
var str = "贺";
console.log(str.charCodeAt()); //36154 十进制
var num = 36154;
console.log(num.toString(16)); //8D3A 十进制转十六进制,这个十六进制就是“贺”的unicode编码
console.log("\u8D3A"); //贺 8D3A是36154的十六进制,\u表示是Unicode编码
console.log(String.fromCharCode(36154)); //贺
console.log(String.fromCharCode('0x8D3A')); //贺
UTF-8
:只有网页上使用。
4.3 GBK:只有中文
五、ES5对象的序列化和反序列化
1. json 转字符: JSON.stringify(str);
且转换后是严格写法的 json 格式字符串;
2. 字符转 json: JSON.parse(str);
要求 str 必须是一个严格写法的 json 格式字符串。否则会报错;
var json = {"name":"admin",age:18};
var str = JSON.stringify(json)
console.log(typeof json);//object
console.log(str);//{"name":"admin","age":18}
console.log(typeof str);//stringconsole.log(JSON.parse(str));//{name: "admin", age: 18}
- 注意:
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的区别
序号 | 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