JS中的数据类型
- JS中的数据类型由基本数据类型和复杂类型组成。
基本数据类型
JS中的基本数据类型有哪些?
Number、String、Null、Undefined、Boolean、Symbol。- ES10新增了一种基本数据类型 BigInt
基本数据类型的检测方法是什么?
typeof可以判断除null之外的基本数据类型属于哪一种具体的基本数据类型,typeof null返回Object。
typeof 1 // "number"
typeof NaN // "number"
typeof '1' // "string"
typeof undefined // "undefined"
typeof true // "boolean"
typeof null // "object"
typeof Symbol() // "symbol"
typeof null 返回 object 的原因
不同的数据类型在底层都表示为二进制,在JavaScript中,二进制前三位都为0的话会被判断为Object类型,null的二进制表示全为0,所以执行typoeof null 会返回'object'。【你不知道的JS上 P103】
如何判断null
var a = null
(!a && typeof a === 'object')//true
怎么理解基本数据类型是不可变的?
通过下图能很好的说明为什么基本类型是不可改变了,我们平时所做的操作其实都是对数据重新赋值。
复杂数据类型
复杂数据类型是 Object
typeof与复杂数据类型
- typeof 函数 会返回
function,其他复杂类型都会返回object
typeof function add (){} //"function"
typeof {} //"object"
复杂数据类型的检测方法:instanceof
obj1 instanceof obj2如果obj1的原型链上有ojb2.prototype,那么返回true。
[] instanceof Array //true
var obj = {}
obj instanceof Object
基本数据类型和复杂数据类型的区别
- 在内存中的存储方式
- 基本数据类型存储在栈中,直接存储的是值。
- 复杂数据类型,在栈中存储的是指向堆中的引用。
- 变量的复制
- 复制基本数据类型,复制的是值的副本,复制之后两个值完全独立互不影响
var a = 1;
var b = a;
a = 2;
b // 1
- 复制复杂数据类型,复制的是引用,复制之后的值也指堆中对应的值
var obj = {
a : 1
}
var obj2 = obj
obj1.a = 2
obj2.a // 2
函数参数是对象的情况
function test(person) {
person.age = 26
person = {
name: 'luoyiluoyi',
age: 30
}
return person
}
const p1 = {
name: 'luoyi',
age: 25
}
const p2 = test(p1)
console.log(p1) // -> ?
console.log(p2) // -> ?
var、let、const的区别
- var 是ES5的语法
- let,const是ES6的语法
- var 存在变量提升
- var 和 let 声明的是变量,可修改,const 声明的是常量,不可修改
- let const有块级作用域,var没有
let 和 const 定义的变量不会出现变量提升,而 var 定义的变量会提升。 let 和 const 是JS中的块级作用域 let 和 const 不允许重复声明(会抛出错误) let 和 const 定义的变量在定义语句之前,如果使用会抛出错误(形成了暂时性死区),而 var 不会。 const 声明一个只读的常量。一旦声明,常量的值就不能改变(如果声明是一个对象,那么不能改变的是对象的引用地址)
强制类型转换与隐式类型转换
强制类型转换
Number
- 数值
Number(1) //1
2.字符串
Number('1')//1
Number('luoyi') //NaN
- 布尔值
Number(true) //1
Number(false) //0
- undefined
Number(undefined) // NaN
- null
Number(null) // 0
- Object
- valueOf()
- toString()
let a = {a:1}
Number(a) //NaN
//过程
a.valueOf() //
a.toString() //
Number(a.toString())
String
- 数值
String(1) // '1'
2.字符串
String('luoyi') //'luoyi'
3.布尔值
String(false) // 'false'
String(true) // 'true'
4.undefined
String(undefined) //'undefined'
5.null
String(null) // 'null'
6.Object
let b = {b:1}
String(b)
//过程
b.toString() //如果是原始类型,那么执行String(b.toString())
b.valueOf() // 如果不是原始类型,valueOf(b.valueOf())。如果b.valueOf()返回的不是原始类型那么报错
Boolean
- Boolean(undefined),Boolean(null),Boolean(0),Boolean(+0),Boolean(-0),Boolean(NaN),Boolean('') 2.其余都为true
隐式类型转换
- 逻辑运算符
- ==
-
- 拼接字符串
[]+[] // ""
[]+{} //"[object Object]"
{}+[] // 0
{}+{} //"[object Object][object Object]"
true + true // 2
1+{a:1} // "1[object Object]"
0.1 + 0.2 !== 0.3
string 类型是不可变的,无论你在 string 类型上调用何种方法,都不会对值有改变。
for of 和 for in 的区别
相同点
- 循环都可以中断
不同的
- for of 遍历的是属性值,for in 遍历的是属性名
- for of 遍历有iterator接口的数据结构。
get请求和post请求有什么不同?
常见的前端攻击方式有哪些?
- XSS攻击
XSS攻击的本质就是将攻击者恶意注入的代码执行。
-
反射型攻击
通过构造URL中的参数拼接恶意代码,页面中是直接读取的URL中的参数,这时候将恶意代码输入到页面中。
-
存储型攻击
通过构造URL中的参数拼接恶意代码,恶意代码被存储到数据库中,页面中从数据库读取数据,这时候将恶意代码输入到页面中。
-
防范措施:
- 前端和后端在传递和接受数据都进行转码和解码。
- 在服务端设置HTTP头
Content-Security-Policy: default-src 'self',或者在前端设置<meta http-equiv="Content-Security-Policy" content="form-action 'self';"> - HTTP-only Cookie: 在cookie中设置HttpOnly属性,那么通过js脚本将无法读取到cookie信息,攻击者完成 XSS 注入后也无法窃取此 Cookie。,这样能有效的防止 XSS 攻击。
- 提交表单的时候增加验证码,防止通过代码的方式提交表单。
- CRFS攻击
攻击者利用登陆了某网站A的用户的登录信息,通过诱导用户点击网站B,在B网站上像A网站发送一些请求。
- 解决方法:
- 根据HTTP请求头Referer判断请求的来源
- 用户每次像服务器提交的诗句都携带一个唯一的Token。
函数
- 函数可以拥有属性,函数的length属性是其声明的参数的个数