JS基础:变量类型和计算
js基础知识:第一个步骤是变量类型和计算,变量是在每个语言中都是最开始要讲的东西,所以js中的知识,我们要把变量类型和计算先梳理一下:
1、题目:先把题目摆出来,思考一下
2、知识点:然后把知识点列出来,类型计算它到底会涉及到哪些知识点
3、解答:根据知识点去解答题目,一开始看到题目可能会有疑惑不会,没法对上之前的思路
1、题目:
- typeof 能判断哪些类型
- 何时使用=== 何时使用==,他们都是在考察基础知识时候非常常考的题目
- 值类型和引用类型的区别
- 手写深拷贝
2、知识点(两部分)
- 变量类型(值类型 vs 引用类型、typeof 运算符、深拷贝)
- 变量计算
3、详情请参考讲师JS基础:
数据类型
在js中的数据类型可以分为两种:
基本数据类型:包括Number、String、Boolean、Undefined、Null、Symbol(es6新增独一无二的值)和Biglnt(es10新增)
引用数据类型:Object。包含Object、Array、 function、Date、RegExp。
备注:基本数据类型,又称值类型。
typeOf运算符
typeof 能有效检测基本类型,检测引用类型都返回object,其中null属于特殊的引用类型返回object,function属于特殊引用类型类型不用于存储数据,typeof检测返回function
变量类型
值类型
// 值类型
let a = 100;
let b = a;
a = 200;
console.log(b) // 100
解析:因为值类型是存放再栈中,一个一个互不干扰,
常见值类型
const a // undefined
// undefined===>必须用let定义,用const会报错
const s = 'abc';
const n = 100;
const b = true;
const s = Symbol('s');
注意:用const声明变量时必须赋值否则会报错,用let,var时则会显示未定义(undefined)
引用类型
// 引用类型
let a = { age:20 }
let b = a;
b.age = 21;
console.log(a.age); // 21
解析:引用数据类型时存放在堆内存中(他只是把变量名存在栈中,让它指向一个内存地址,地址中存放的才是数据)它改变b.age就相当于改变了堆内存中的数据,而a也指向的是同一个堆内存,所以a.age也会发生改变。
常见引用类型
const obj = { x:100 }
const arr = { 'a','b','c' }
const n = null // 特殊引用类型,指针指向为空地址
// 特殊引用类型,但不用于存储数据,所以没有“拷贝、复制函数”这一说
function fn() {}
值类型和引用类型的区别
const obj1 = { x:100,y:200 }
const obj2 = obj1;
let x1 = obj1.x;
obj2.x = 101;
x1 = 102
console.log(obj1); // { x:101 }
typeof 运算符(能干嘛)
1、识别所有值类型
2、识别函数
3、判断是否是引用类型(不可再细分)
// 判断所有的值类型
let a; typeof a // 'undefined'
const str = 'abc'; typeof str // 'string'
const n = 100; typeof n // 'number'
const b = true; typeof b // 'boolean'
const s = Symbol('s'); typeof s // 'symbol'
// 能判断函数
typeof console.log // 'function'
typeof function() {} // 'function'
// 能识别引用类型(不能再继续识别)
typeof null // 'object'
typeof ['a','b'] // 'object'
typeof { x:100 } // 'object'
深拷贝
/**
* 深拷贝
**/
const obj1 = {
age:20,
name:"xxx",
address:{
city:"beijing"
},
arr:['a','b','c']
}
const obj2 = deepClose(obj1);
obj2.address.city = 'shanghai';
obj2.arr[0] = 'al';
console.log(obj1.address.city);
console.log(obj1.arr[0]);
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
**/
function deepClose(obj = {} {
if(typeof obj !== 'object' || obj == null){
// obj 是 null ,或者不是对象和数组,直接返回
return obj
}
// 初始化返回结果
let result
if(obj instanceof Array) {
result = []
} else {
result = {}
}
for(let key in obj){
// 保证 obj 不是原型的属性
if(obj.hasOwnProperty(key) {
// 递归调用!!!
result[key] = deepClose(obj[key]);
})
}
// 返回结果
return result
})
注意:
- 注意判断值类型和引用类型
- 注意判断是数组还是对象
- 递归
变量计算 - 类型转换
- 字符串拼接
- == (运算符)
- if 语句和逻辑运算
字符串拼接
const a = 100 + 10 // 110 // 数值型直接相加
const b = 100 + '10' // '10010' // 只要有字符串,它就不是加法,是字符串拼接
const c = true + '10' // 'true10'
== 运算符
100 == '100' // true
0 == '' // true
0 == false // true
false == '' // true
null == undefined // true
// 除了 == null 之外,其他都一律用 ===,例如:
const obj = { x:100 }
if(obj.a == null) { }
// 相当于
// if(obj.a === null || obj.a === undefined) {}
if 语句和逻辑运算
※ truly 变量:!!a === true 的变量
※ falsely 变量:!!a === false 的变量
// 以下是 falsely 变量。除此之外都是 truly 变量
!!0 === false
!!NaN === false
!!'' === false
!!null === false
!!undefined === false
!!false === false
if 语句
// truly 变量
const a = true;
if(a) {
//....
}
const b = 100;
if(b) {
//....
}
// falsely 变量
const c = '';
if(c) {
//....
}
const d = null;
if(d) {
//...
}
let e
if(e) {
//...
}
逻辑判断
console.log(10 && 0) // 0
console.log('' || 'abc') // 'abc'
console.log(!window.abc) // true
总结
- 值类型 vs 引用类型,堆栈模型,深拷贝
- typeof 运算符
- 类型转换,truly 和 falsely 变量