字符串中查找某个字符所有的位置
```bash
(function sum (item){
var arr = 'indexhdfhsvfdgdindexbindex'
console.log(item,'item') //index item
var index = arr.indexOf(item)
console.log(index,'index') //0 index
var num = 0
while (index >= 0) {
num++
index = arr.indexOf(item, index + 1)
}
console.log('共出现'+num+'次') //共出现3次
})('index')
js 判断字符串为空或者不为空
1、 判断字符串为空
var test="";
if(test==""||test==null||test==undefined){
console.log("为空");//为空
}
if(!test){
console.log("为空");//为空
}
2、 判断字符串不为空
var test="1";
if(test!=""&&test!=null&&test!=undefined){
console.log("不为空");//不为空
}
if(!!test){
console.log("不为空");//不为空
}
js对象转换为数组的两种方法
1、Object.values(obj)
var obj = {
length: 3,
age:18
}
var arrs = Object.values(obj)
console.log(arrs); //[ 3, 18 ]
2、for-in
var obj = {
length: 3,
age:18
}
var arrs =[]
for(key in obj){
console.log(key,'key');
//length key
//age key
arrs.push(obj[key])
}
console.log(arrs); //[ 3, 18 ]
JS中检测数据类型的方法
无论是数组还是对象,对于typeof的操作返回值都为object,所以就有了区分数组类型和对象类型的需要:
四种:
1:Object.prototype.toString.call(待检测值)(推荐)
var arr = [1, 2, 3];
var obj = {
name: 'zqf',
age: 18,
1: 'name'
}
console.log(Object.prototype.toString.call(arr) === '[object Array]'); //true
console.log(Object.prototype.toString.call(boj) === '[object Array]'); //false
2 typeof
typeof漏洞很多,无法检测null、数组、日期、正则、对象,结果全为object
原因:typeof是直接在计算机里面基于二进制值进行检测的,也就是数据类型都是二进制值,对象存储在计算机中,二进制的值都是以000开头,而null值为000,所以typeof(null)为object
let a = 1
let b = "1"
let c = false
let d = undefined
let e = function(){}
console.log(typeof(a))//number
console.log(typeof(b))//string
console.log(typeof(c))//boolean
console.log(typeof(d))//undefined
console.log(e)//[Function: e]
let f = []
let g = null
let h = new Date()
let i = new RegExp()
let j = {}
console.log(typeof(f))//object
console.log(typeof(g))//object
console.log(typeof(h))//object
console.log(typeof(i))//object
console.log(typeof(j))//object
3:instanceof
a instanceof Array 返回一个布尔值用于判断a是否为Array的一个实例,但是无法检测基本数据类型
let arr = []
console.log(arr instanceof Array)//true
console.log(arr instanceof Object)//true
let a = 1
let b = "123"
let c = false
console.log(a instanceof Number)//false
console.log(b instanceof String)//false
console.log(c instanceof Boolean)//false
4:constructor
constructor比instanceof好的地方是,它可以检测基本数据类型
let a = 1
let b = "123"
let c = false
console.log(a.constructor === Number)//true
console.log(b.constructor === String)//true
console.log(c.constructor === Boolean)//true
而且,也不会顺着原型链找
let arr = []
console.log(arr.constructor === Array)//true
console.log(arr.constructor === Object)//false
缺点是我们可以随意更改constructor,例如
let arr = []
Array.prototype.constructor = 'a' //更改constructor
console.log(arr.constructor === Array)//false
总结
① Object.prototype.toString.call(待检测值)是最标准的
② typeof只能检测除null外的基本数据类型,对于数组、对象、正则等都返回为Object
③ instanceof不能检测基本数据类型,检测引用类型时会顺着原型链往上找,只要原型链上有的,都返回true,同时,可以随意更改原型链的指向,导致检测结果不准确
④ constructor可以检测基本数据类型,也能分辨出数组和对象,但是我们可以随意更改constructor的值,导致检测结果不准确
js数组遍历和对象遍历
JS数组遍历
1,普通for循环,经常用的数组遍历
var arr = [2,4,6,834];
for ( var i = 0; i <arr.length; i++){
console.log('下标:'+ i+',值:'+arr[i]);
}
// 下标:0,值:2
// 下标:1,值:4
// 下标:2,值:6
// 下标:3,值:834
2,forEach,数组自带的循环,主要功能是遍历数组
forEach这种方法也有一个小缺陷:你不能使用break语句中断循环,也不能使用return语句返回到外层函数。
var arr = [2,4,6,834];
arr.forEach(function(value,i){
console.log('下标:'+i+',值:'+value);
})
// 下标:0,值:2
// 下标:1,值:4
// 下标:2,值:6
// 下标:3,值:834
3,map遍历,map即是 “映射”的意思 用法与 forEach 相似
var arr = [2,4,6,834];
var temp=arr.map(function(val,index){
console.log('下标:'+index+',值:'+val);
return val*val
})
console.log(temp);
// 下标:0,值:2
// 下标:1,值:4
// 下标:2,值:6
// 下标:3,值:834
// [ 4, 16, 36, 695556 ]
4,for-of遍历
它可以正确响应break、continue和return语句
for-of循环支持数组,还支持类对象(例如DOM NodeList对象),字符串,map对象,set对象
var arr1 = [2,4,6,834];
for (let i of arr1){
if(i == 6) break
console.log(i)
}
// 2
// 4
// 遍历普通对象报错
var obj2 = {fname:1, name2:22}
for(let val of obj2){ //TypeError: obj2 is not iterable
console.log(val)
}
JS对象遍历:
1,Object.keys()遍历对象
###1.1,在实际开发中,我们有时需要知道对象的所有属性,Object.keys(),传入对象,返回属性名并放在数组里
var obj = {'age':'123','ag2':'345'}
console.log(Object.keys(obj))
// [ 'age', 'ag2' ]
###1.2,Object.keys().forEach() 遍历对象,把对象的属性名转成数组,可与数组遍历结合使用
var person = {
name: 'hhh',
age:'20',
sex:'男',
home:'china'
}
var keys = Object.keys(person).forEach((e) =>{
console.log('person', e, ':', person[e])
})
// Object.keys 遍历对象,把对象的属性名转成数组,可与数组遍历结合使用
var keys2 = Object.keys(person)
console.log(keys2)
// ["name", "age", "sex", "home"]
2,for-in遍历对象
for…in遍历对象,它遍历的是属性名
会遍历实例的属性,还会遍历整个原型链**,这可能不是你所期望的结果,然后从性能角度上看Object.keys会更优。
var obj = {'a':'123','b':'345'}
for (let key in obj){
console.log(key ,obj[key])
}
// a 123
// b 345
for-in是为遍历对象而设计的,不适用于遍历数组。
遍历数组的缺点:for-in遍历的index值"0",“1”,"2"等是字符串,会把属性名排序
for (var index in arr){
console.log(arr[index]);
console.log(index);
}
let obj2 = {b:2, a:'11', 1:'ok'}
for (let key in obj2) {
console.log(key)
}
// 1
// b
// a
for…in总结:
1、for in遍历对象时,会遍历实例的属性+还遍历原型中可枚举的属性
2、for in不适合遍历数组,遍历数组遍历的是下标,下标类型是 字符串
3,for in遍历会以任意顺序遍历对象的属性名
在字符串中查找某个字符所有的位置
```bash
(function sum (item){
var arr = 'indexhdfhsvfdgdindexbindex'
console.log(item,'item') //index item
var index = arr.indexOf(item)
console.log(index,'index') //0 index
var num = 0
while (index >= 0) {
num++
index = arr.indexOf(item, index + 1)
}
console.log('共出现'+num+'次') //共出现3次
})('index')
字符串转换为数组的4 个方法
1、split() 方法
常见的转换技术是split字符串方法,但这也是有问题的一种。
通过使用空字符串作为split方法的分隔符,我们可以将字符串转换为字符数组。
const text = "abc";
const chars = text.split('');
console.log(chars);
//['a', 'b', 'c']
该split方法无法正确处理采用两个代码单元(如表情符号)的字符。下面是一个例子。
const text = "abc????";
const chars = text.split('');
console.log(chars);
//["a", "b", "c", "\ud83d", "\ude0e"]
2、展开运算符
展开运算符 ( …) 允许在需要多个元素(如数组文字)的地方扩展诸如字符串之类的可迭代对象。
这是将字符串扩展为字符数组的示例。正确处理采用两个代码单元的字符。
const text = "abc????";
const chars = [ ...text ];
console.log(chars);
//["a", "b", "c", "????"]
3、解构赋值
解构赋值语法可以将数组或可迭代对象中的值解包为不同的变量。
在解构数组或可迭代对象时,我们可以使用 rest 模式将其剩余部分提取到单个变量中。
const text = "abc????";
const [ ...chars ] = text;
console.log(chars);
//["a", "b", "c", "????"]
4、Array.from
Array.from辅助创建从阵列状或迭代的对象的新数组。字符串既可迭代又类似于数组,因此,可以成功地将其转换为字符数组。
const text = "abc????";
const chars = Array.from(text);
console.log(chars);
//["a", "b", "c", "????"]
重点说明
该split方法可能是将字符串转换为字符数组的常用方法,但它不处理采用两个代码单元的字符。
我们可以使用对象字面量中的扩展运算符、使用数组解构赋值语法中的剩余模式或Array.from实用程序将字符串正确转换为字符数组。
前端js实现字符转义和反转义
什么是XSS?
XSS攻击又称为跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行。XSS是一种经常出现在Web应用程序中的计算机安全漏洞,是由于Web应用程序对用户的输入过滤不足而产生的,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
举个栗子: 在数据库中写入一段代码,然后前端通过请求等方式获取到这段代码在页面中渲染,访问页面时就会被执行,浏览器就会弹出1的弹窗,这就最简单的XSS攻击。
怎么避免XSS?
前端处理: 使用字符转义,将’<‘、’>'等字符进行转义<、>
后端处理: 也是一样的道理,将相关的字符给转义,就可以避免XSS
字符转义(解决XSS)
直接调用下面的htmlEscape(‘’)方法,就可以过滤掉存在XSS风险的相关字符:
function htmlEscape(str) { //字符转义
var escapesMap = {
'<': '<',
'>': '>',
'"': '"',
"'": '''
},
reUnescapedHtml = new RegExp(/[<>"']/g);
return (str && reUnescapedHtml.test(str)) ? str.replace(reUnescapedHtml, function(chr) {
return escapesMap[chr];
}) : (str || "");
}
字符反转义
有时候在写逻辑的时候,可能需要反转义,就用下面的htmlUnEscape方法:
function htmlUnEscape(str) { //反转义
var unescapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
''': "'"
},
reEscapedHtml = new RegExp(/&(?:amp|lt|gt|quot|#39);/g);
return (str && reEscapedHtml.test(str)) ? str.replace(reEscapedHtml, function(entity) {
return unescapes[entity];
}) : (str || '')
}