目录
ES5:null,undefined,number,string,boolean
ES5:Object,function,Array,Date,RegExp
改变Array的方法:进出*4,splice,sort,reverse,fill
Map/set(有序):任何值类型都可以作为键/值,size,可迭代,删减优化
Object(无序):键:String、Symbol,JSON序列化JSON.stringify()和解析JSON.parse()
引用string实例的属性、方法时:字面量string会临时转换为对象
typeof:判断 基本数据类型+ 广义函数(function、promise、箭头函数)
typeof NaN==Number:全局方法isNaN()
构造函数.prototype.isPrototypeOf(实例) :判断原型链
(数据).constructor === 数据类型:不包含继承类型
基本数据类型、function,Array,RegExp:返回数据本身
Object,(Weak)Map、(Weak)Set:[object 类型]
Date:...中国标准时间(ECMAScript规范定义的日期时间字符串格式)
Number(任意类型):任意类型->string、若string含非数字,会返回NaN
BigInt 抛出 TypeError,以防止意外的强制隐式转换导致精度损失
parseInt(string[,radix]):基数radix是2-36之间的整数
parseFloat(string):解析一个参数并返回一个浮点数,无法识别 0x 前缀
parseInt(string[,radix]):基数radix是2-36之间的整数
parseFloat(string):解析一个参数并返回一个浮点数
Boolean():0, ''(空字符串), null, undefined, NaN会转成false,其它都是true
null、undefined、boolean基本类型:转Number
obj、function、arr、Date等引用类型:转string
因为只有[]\[num]这两类特殊的数字才能转换为Number、所以为了统一,arr:转string优先于Number
全局属性 NaN :非数字的值,它与任何其他值(包括自身)都不相等
isNaN(string/Number/boolean/null)
Object.is(val0, val1):NaN等,±0不等
数据类型
基本:栈/(闭包在堆)
原始值(原始数据类型)
- 非对象,无属性/方法
在原始值上访问属性时,自动将值装入包装临时对象(自动装箱行为)
- 不可修改
不要将原始值本身与分配了原始值的变量混淆
let str = "hello";
// 尝试给字符串添加一个属性
str.foo = "bar";
console.log(str.foo); // 输出: undefined
console.log(str); // 输出: "hello"
- 占用空间
基本数据类型占用空间小、大小固定,通过值来访问,属于被频繁使用的数据
闭包中的基本数据类型变量是保存在堆内存里的,当函数执行完弹出调用栈后,返回一个内部函数的一个引用,这时候函数的变量就会转移到堆上,因此内部函数依然能访问到上一层函数的变量。
ES5:null,undefined,number,string,boolean
ES6:symbol
console.log(symbol2 === 42);
// Expected output: false
console.log(Symbol('foo') === Symbol('foo'));
// Expected output: false
ES10:bigint
let bnum=1684424684321231561n //方式1:数组后加n
bunm=BigInt("1684424684321231561")//方式2:调用BigInt
引用:(栈中存储指针,指向堆中数据的起始地址)
二叉堆,引用数据类型占据空间大、大小不固定,如果存储在栈中,将影响程序的运行性能。
引用数据类型会在栈中存储一个指针,这个指针指向堆内存空间中该实体的起始地址。
ES5:Object,function,Array,Date,RegExp
改变Array的方法:
进出*4,splice,sort,reverse,fill
Array:索引
是非负整数(或字符串),基于连续内存
数组基于Object
实现,属性名是字符串;隐式的 toString将
数字索引自动转换成字符串
因此索引'2'
!='02'
let myArray = [];
myArray[0] = "Apple";
myArray["asd"] = "Banana";
myArray["2"] = "Cherry";
console.log(myArray)//Array ["Apple", undefined, "Cherry"]
Map/set(有序):
任何值类型都可以作为键/值,size,可迭代,删减优化
迭代:for in,for of,forEach
关联数组(字典或映射):每个键(通常是字符串)都与一个值关联。
Object(无序)
:键:String、Symbol,JSON序列化JSON.stringify()和解析JSON.parse()
迭代:for in,
ES6:Promise(解决回调地狱),Proxy
Map:键/值对
底层优化
映射设置值时会将键和值添加到这两个数组的末尾。从而使得索引相对应。
取/赋值,需要
O(n)
强引用(哪怕不被引用了,也会阻止垃圾自动回收),导致内存泄漏
WeakMap:
键必须是对象或非全局symbol
(此处的键值对都是对象)
当键被回收+值没被引用,则值回收
当值回收,不影响键
symbol是保证唯一的,并且不能被重新创建,和对象引用地址一样
非全局意味着有生命周期,可以被释放 对应着 对象不再被引用,然后被回收
ES14:Symbol 可作为 WeakMap 键
Set:任何值
WeakSet:
值必须是对象或非全局symbol
weak弱引用对象,不被引用时会被回收,所以weakmap键和weakset值必须是对象
WeakMap因为
获取键的列表会依赖于垃圾回收的状态,所以不允许观察其键的生命周期,不允许枚举;
new Proxy(target, handler)
包装target (对象/数组/函数甚/proxy对象)
被代理对象上的自定义行为(定义一组处理函数(例如get、set)的对象)
const target = {
notProxied: "original value",
proxied: "original value",
};
const handler = {
//target:被代理者(就是上面的target)
//prop:被代理者的属性
//receiver:代理者 Proxy 或者继承 Proxy 的对象
get: function (target, prop, receiver) {
if (prop === "proxied") {
return "replaced value";
}
return Reflect.get(...arguments);//调用原始对象上相同的属性,保持属性的原始值不变
},
};
const proxy = new Proxy(target, handler);
console.log(proxy.notProxied); // "original value"
console.log(proxy.proxied); // "replaced value"
ts
在 js 中, 以 number 与 Number 举例,后者是前者的包装对象
在 ts 中,以 number 与 Number 举例,前者是 ts 中的类型,后者是 js 中的对象
总结:在 ts 中使用小写来定义参数类型(如 age:number)
判断数据类型
字面量:数据固定值,不用构造函数创建
基本类型:不属于引用类型
//基本类型 console.log(typeof 'str'); // 输出 "string" //引用类型 console.log(String.prototype.isPrototypeOf('str')); // false console.log('str' instanceof String); // false
引用string实例的属性、方法时:字面量string会临时转换为对象
console.log(String.prototype.isPrototypeOf('str')); // false console.log('str'.length); // 3 console.log('str'.includes('s')); //true
引用类型:仍然是引用类型
console.log(typeof {}); // 输出 "object"
运算符
typeof:判断 基本数据类型+ 广义函数(function、promise、箭头函数)
typeof null=Object 类型标签均为000
typeof NaN==Number:全局方法isNaN()
// 基本类型的字面量
console.log(typeof undefined); // 输出 "undefined"
console.log(typeof null); // 输出 "object"(历史遗留 Bug)
console.log(typeof true); // 输出 "boolean"
console.log(typeof 42); // 输出 "number"
console.log(typeof NaN); // 输出 "number"
console.log(typeof 'string'); // 输出 "string"
console.log(typeof Symbol()); // 输出 "symbol"
console.log(typeof BigInt(42)); // 输出 "bigint"
// 特殊引用类型 function
console.log(typeof function(){}); // 输出 "function",匿名函数
console.log(typeof (() => {}).prototype); // 输出 "function",但并非function实例对象
console.log(typeof Promise); // 输出 "function",异步函数设计
console.log(Function.prototype.isPrototypeOf(new Promise(()=>{}))); // false
// 引用类型
console.log(typeof {}); // 输出 "object"
console.log(typeof []); // 输出 "object"
console.log(typeof new Date()); // 输出 "object"
console.log(typeof /regex/); // 输出 "object"
console.log(typeof new Map()); // 输出 "object"
console.log(typeof new Set()); // 输出 "object"
console.log(typeof new WeakMap()); // 输出 "object"
console.log(typeof new WeakSet()); // 输出 "object"
实例
instanceof 构造函数
:判断原型链
Object.prototype.isPrototypeOf({})// true
{} instanceof Object// true
方法
构造函数.
prototype.isPrototypeOf(实例)
:判断原型链
(数据).constructor === 数据类型:不包含继承类型
(1).constructor ===Number//true
//()转换为Number
显示
toString,valueOf
除了null,undefined
基本数据类型、function,Array,RegExp:返回数据本身
//基本数据类型
//ES5:Null,Undefined,Number,String,Boolean
//ES6:Symbol
//ES10:Bigint
console.log(Symbol('foo').toString());//"Symbol(foo)"
console.log(Symbol('foo').valueOf());//Symbol(foo)
引用数据类型
Object,(Weak)Map、(Weak)Set:[object 类型]
Date:...中国标准时间(ECMAScript规范定义的日期时间字符串格式)
valueOf:this
值转换为对象
let set=new Set()
set.add(1)
console.log(set.toString()); //"[object Set]"
console.log(set.valueOf()); //[object Set]
let mp=new Map()
mp.set("1",1)
console.log(mp.toString()); //"[object Map]"
console.log(mp.valueOf()); //[object Map]
toString:重写对象的类型转换
//"Sun Dec 17 1995 03:24:00 GMT+0800 (中国标准时间)"
console.log(new Date("December 17, 1995 03:24:00").toString());
类型转换
Number
数字字面量:浮点数值
像 37
这样的数字字面量是浮点数值,而不是整数。JavaScript 没有单独的整数类型。
显式类型转换
Number(任意类型):任意类型->string、若string含非数字,会返回NaN
[num]为num
undefined、{} 为 NaN
null 、[]、''空字符串或仅包含空格的字符串、为 0
console.log(Number({}))//NaN
console.log(Number([]))//0
console.log(Number([1]))//1
console.log(Number(null))//0
console.log(Number(undefined))//NaN
BigInt 抛出 TypeError,以防止意外的强制隐式转换导致精度损失
Symbol 抛出 TypeError
Date:秒
Number(new Date("December 17, 1995 03:24:00"));//819199440000
前导和尾随的空格/换行符会被忽略
前导的数字 0
不会导致该数值成为八进制字面量
Number("0x11"); // 17
Number("0b11"); // 3
Number("0o11"); // 9
+
和 -
是独立的一元运算符,后面不能跟空格
不允许使用数字分隔符
parseInt(string[,radix]):基数radix是2-36之间的整数
parseFloat(string):解析一个参数并返回一个浮点数,无法识别 0x
前缀
区别:pase类自动截断尾部非数字,Number不会截断
console.log(parseInt('6f'));//6
console.log(parseFloat('6f'));//NaN
console.log(Number('6f'));//6
parseInt(string[,radix]):基数radix是2-36之间的整数
parseFloat(string):解析一个参数并返回一个浮点数
隐式转换:+str-,含boolean的相加
str = '123'
-
str - 1 //122
-
+str+1 // 124
-
str+1 // '1231'
String
显式类型转换
除了null/undefined.toString()
String(任意类型)
隐式转换:含str的相加
+''
Boolean
显式类型转换
Boolean():0, ''(空字符串), null, undefined, NaN会转成false,其它都是true
隐式转换 :!!
比较
字符串:字符顺序(等长),长的大(短是长的前缀)
console.log('apple' < 'banana'); // true,因为 'a' 在 Unicode 中比 'b' 小
console.log('apple' < 'apples'); // true,因为 'apple' 是 'apples' 的前缀
console.log('apple' < 'apricot'); // true,因为 'l' 在 Unicode 中比 'r' 小
相加减:交换顺序后结果不变
num相加
console.log(Number([1]))//1
console.log(Number([]))//0
console.log(Number(null))//0
console.log(Number({}))//NaN
console.log(Number(undefined))//NaN
null、undefined、boolean基本类型:转Number
console.log(1+null); //1
console.log(undefined+1); //NaN
obj、function、arr、Date等引用类型:转string
console.log({}+1)//[object Object]1
console.log(1+{a:1,b:2})//1[object Object]
console.log(typeof(1+{a:1}))//string
console.log(1+function(){console.log()}); "1function(){console.log()}"
因为只有[]\[num]这两类特殊的数字才能转换为Number、所以为了统一,arr:转string优先于Number
console.log([]+1); // "1"
console.log(1+[]); // "1"
console.log(1+['a'])//1a
console.log(1+['a',2])//1a,2
console.log(1+[2,2])//12,2
console.log([0,1]+[2,2])//0,12,2
num相减:能转number就转,不能则NaN
//number与其他数据相加减
//:能转number就转,不能则转string相加,object,arr(元素超过1个 或者 非number元素)
console.log(1-{})//NaN
console.log(1-[])//1
console.log(1-[1])//0
console.log(1-['a'])//NaN
console.log(1-null)//1
相等
全局属性 NaN
:非数字的值,它与任何其他值(包括自身)都不相等
isNaN(string/Number/boolean/null)
Object.is(val0, val1):NaN等,±0不等
只能比较字面量,对象只会判为false
const obj = {};
console.log(Object.is(obj, {}));
// Expected output: false
===、==:NaN不等、±0等
Object.is()
使用了 "SameValueZero" 比较算法,它不会对 NaN
进行特殊处理,而是按照严格的值相等性规则比较
console.log(NaN===NaN);
// Expected output: false
console.log(NaN==NaN);
// Expected output: false
console.log(Object.is(NaN, NaN));
// Expected output: true
console.log(Object.is(-0, +0));
// Expected output: false
console.log(Object.is(null, undefined));
// Expected output: false
松散相等==(可自动转换类型) 和 严格相等===
比较的是内存单元的内容
255 === 255.0; // true
255 === 0xff; // true(十六进制表示)
255 === 0b11111111; // true(二进制表示)
255 === 0.255e3; // true(十进制指数记数法)
对象传递是引用地址:判断对象相等,需要深度比较
const obj = {};
console.log(Object.is(obj, {}));
// Expected output: false
set用===判断是否相等
//Set用===判断是否相等
const set= new Set();
const obj1={ x: 10, y: 20 },obj2={ x: 10, y: 20 }
set.add(obj1).add(obj2);
console.log(obj1===obj2);//false
console.log(set.size);// 2
set.add(obj1);
console.log(obj1===obj1);//true
console.log(set.size);//2
对象判空
JSON.stringify(obj) == '{}'
Object.keys(obj).length==0