01、Object对象

[**Object**](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object)是 JavaScript 的一种 数据类型,它用于存储各种键值集合和更复杂的实体,是一组数据和功能的集合。JS中几乎所有对象都是继承自Object,其他如Array、RegExp、Math、Map、Set都是他的子类型。

  • 标准对象结构**{ key(字符串/Symbol) : value(任意类型), ...}**
  • 创建方式:new Ojbect()、字面量{key:value,key:value}Object.create(obj)
    • 使用new 构造器(),实现可重用的对象创建,任何函数都可以用于构造器(箭头函数除外),一般约定首字母大写,没有return返回值。
  • 使用对象.属性=value对象["属性名"]=value,属性(Key)存在则赋值,不存在则创建并赋值。
  • 删除属性delete obj.prop
  • 检测属性"key" in obj,返回bool
  • 遍历属性for(let key in obj)循环所有key。 | 属性/方法 | 描述 | | —- | —- | | 静态属性/方法 | | | Object.create(proto) | 使用指定的原型对象和属性创建一个新对象 | | Object.assign(target,…source)IE🚫 | 合并多个source对象到target对象并返回,复制一级属性的值,不能作为深拷贝。 | | Object.defineProperty(obj,prop) | 给对象添加一个属性 | | Object.entries(obj)IE🚫 | 返回给定对象自身可枚举属性的 [key, value] 数组(二维数组) | | Object.keys(obj) | 返回给定对象自身可枚举属性组成的数组 | | Object.values(obj)IE🚫 | 返回给定对象自身可枚举值组成的数组 | | Object.freeze(obj) | 冻结对象:其他代码不能删除或更改任何属性。 | | Object.getOwnPropertyDescriptor(o,p) | 返回对象指定属性的描述符,IE🚫 | | Object.getOwnPropertyNames(obj) | 所有自身属性的属性名(包括不可枚举属性不包括 Symbol 名称的属性)组成的数组 | | Object.getPrototypeOf(obj) | 返回指定对象的原型,(prototype /ˈprəʊtətaɪp/ 原型) | | Object.is(v1,v2) | 判断两个值是否为同一个值,支持值类型、引用类型 | | Object.isSealed() | 判断一个对象是否被密封 | | 构造函数 | | | Object() | 构造函数将给定的值包装为一个新对象 | | 实例属性/方法 | | | constructor | 指向 Object 构造函数 | | proto | 指向实例化的原型对象,已废弃,推荐Object.getPrototypeOf() | | hasOwnProperty(prop) | 判断指定对象自身是否存在指定属性 | | propertyIsEnumerable(prop) | 判断属性是否可枚举,枚举属性可被for…in循环迭代 | | isPrototypeOf(obj) | 判断是否在另一个对象的原型链上 | | toLocaleString() | 调用 toString() | | toString() | 返回字符串,可以重写 | | valueOf() | 返回对象的原始值 |
  1. const obj1={};
  2. const obj2={
  3. name:"zhagnsan",
  4. "age":"3",
  5. school:{ //属性值也是对象
  6. name:"龙腾幼儿园",
  7. address:"那边",
  8. },
  9. sayHello:function(name){ //属性值是函数
  10. console.log("hello "+name);
  11. },
  12. }
  13. obj2.sayHello("sam");
  14. obj2.birthday="2022-12-12";//赋值操作:属性(Key)存在则赋值,不存在则创建+赋值
  15. //可以用null为原型创建一个干净的对象,不会从从Object.prototype继承任何属性方法
  16. const nobj = Object.create(null, { name: { value: "sam", enumerable: true } });
  17. nobj.age = 20;
  18. nobj.toString=Object.prototype.toString; //赋予toString()方法
  19. Object.getOwnPropertyNames(["a","b"]) //[ "0", "1", "length" ]
  20. Object.keys(["a","b"]) //[ "0", "1" ]
  21. Object.getPrototypeOf([]); //Array []
  22. const obj={name:"sam",sex:"male",say:function(){}};
  23. obj.hasOwnProperty("name"); //true
  24. obj.propertyIsEnumerable("name"); //true
  25. obj.toString = function(){return JSON.stringify(this)};

对象属性

通过Object.**getOwnPropertyDescriptor**(obj,propertyName)方法可以获取一个属性的完整信息,返回的是一个“属性描述符”对象,包括几个主要属性:

  • writable :是否只读,true=可读可写。
  • enumerable :是否支持枚举。
  • configurable :如果为 true,则此属性可以被删除。
  • value:属性的值

通过Object.**defineProperty**(obj, propertyName, descriptor)方法可添加/设置一个属性,属性描述符**descriptor**默认值都是false。JS的一些内置属性就是只读、不可删除的,如Math.PI

  1. function User(name, age) {
  2. this.name = name;
  3. this.age = age ? age : 18;
  4. function sayHi() { console.log("Hi,I'm " + name) };
  5. }
  6. let u1 = new User("sam");
  7. let pname = Object.getOwnPropertyDescriptor(u1, "name");
  8. //设置name值不可更改
  9. Object.defineProperty(u1, "name", { writable: true });

image.png
descriptor主要结构如下:Object。Object.create(proto, propertiesObject)的第二个参数也是用的这个结构来描述属性。

  1. let descriptor = {
  2. enumerable: false,
  3. configurable: false,
  4. writable: false,
  5. value: "value",
  6. get() { },
  7. set() { },
  8. }
  9. let pobj = { //Object.create(proto, propertiesObject)的第二个参数
  10. proName1: descriptor,
  11. proName2: descriptor,
  12. }

getter/setter属性访问器

对象中常用的属性都属于“数据属性”,存放数据没有额外逻辑。而访问器属性(accessor property),表现形式和普通属性一样,本质上一个取值、设置值的函数,可自定义逻辑,如数据合法性验证。

  1. //只支持在字面量对象里使用访问器,而且“私有”变量_name还是会暴露出去。
  2. let obj = {
  3. age: 18,
  4. set name(value) {
  5. let vs = String(value);
  6. if (!vs || vs.length < 4 || vs.length > 12) {
  7. throw Error("值必须是4到12的有效字符");
  8. }
  9. this._name = value;
  10. },
  11. get name() {
  12. this._name ??= "sam";
  13. return this._name;
  14. }
  15. };
  16. function User(name, age) {
  17. this.age = age ? age : 18;
  18. function sayHi() { console.log("Hi,I'm " + name) };
  19. //构造器里加访问器就是麻烦,而且_name还是会暴露出去
  20. Object.defineProperty(this, "name", {
  21. set(value) {
  22. if (!value || value.length < 4 || value.length > 12) {
  23. throw Error("值必须是4到12的有效字符");
  24. }
  25. this._name = value;
  26. },
  27. get() { return this._name; }
  28. })
  29. }
  30. let user = new User("sam");

02、JSON数据

JOSN(JavaScript Object Notation /nəʊˈteɪʃn/)是一种描述对象数据的语法,是一种通用的键值数据格式,很多语言都支持,用来存储、传输、处理数据。和Object定义相似,不同的是,属性名必须双引号包起来,属性值仅允许字符串,数字,数组,true,false,null或其他(JSON)对象,不支持函数。
image.png

  • **JSON.**[**stringify**](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)**(obj)**:对象转换(序列化)为字符串。
  • **JSON.**[**parse**](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)**(jsonstr)**:字符串反序列化为Json对象。 ```javascript let jobj={“name”:”same”};

let str1=JSON.stringify({name:”zhangsan”,age:11}); //‘{“name”:”zhangsan”,”age”:11}’ let obj1=JSON.parse(str1);

const jurl = “https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json“; let request = new XMLHttpRequest(); request.responseType = “json”; request.open(“GET”, jurl); request.onload = function () { let jobj = request.response; console.log(jobj); let h1=document.createElement(‘h1’); h1.textContent=jobj.squadName; document.body.appendChild(h1); } request.send();

  1. <a name="nfmEc"></a>
  2. # 03、Array数组
  3. `[**Array**](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array)`数组是按序号排列的一组数据,从0开始,数组没有大小限制(不管是否设置了数组大小),长度可变,数据类型可以任意,很自由很渣!也不会报越界的错误。
  4. - 通过`array[索引下标]`访问、设置数组元素。
  5. - 通过length属性获取、设置长度。
  6. - 可附加属性(Array属于对象),使用“非正整数”作为索引时,会附加属性,不影其器数组大小。
  7. ```javascript
  8. var arr1=[1,2,3,4];
  9. var arr2=new Array(1,2,3,4); //new并指定数据
  10. var arr3=new Array(3); //指定数组长度,别相信它,它是会变心的。
  11. console.log(arr3.length); //3
  12. console.log(arr3[6]); //可以越界访问,返回undefined
  13. arr3[6]="666";
  14. console.log(arr3.length); //长度为7了
  15. arr3.length=10;
  16. arr3["name"]="sam"; //附加了属性name
  17. console.log(arr3.name); //sam
  18. arr3["12"]="sam123"; //等同于arr3[12]

🔸数组遍历

  • 索引下标:遍历索引下标进行访问。for(var i=0;i<arr3.length;i++)
  • **for...in**遍历数组里面的所有下标(键),包括数字索引、属性Key。
  • **for...each**循环遍历集合的数值、索引下标,只有正常数组的部分。

🔸数组方法/属性

属性/方法 描述 备注
静态属性/方法
Array.from()IE🚫 创建一个新的,浅拷贝的数组实例:Array.from(arrayLike,mapFn?) Array.from("123")
Array.isArray(arr) 判断是否Array,和instanceof Array差不多 Array.isArray([]); //true
Array.of()IE🚫 根据可变参数创建数组:Array.of(v0,v1,…vN)
构造函数
Array() 创建一个新的 Array 对象:new Array(v0,v1,…vN) 、new Array(len)
实例属性/方法
length 元素个数
indexOf(v) indexOf(value,start?):查找值的索引位置,从前往后,start默认0。 arr1.concat(7,["a","b"])
lastIndexOf(v) lastIndexOf(value,start?):查找值的索引位置,从后往前
find(func)IE🚫 查找符合条件的元素值,类似方法findIndex()只返回索引
includes(v)IE🚫 判断是否包含指定的值
push(v)、pop() push末尾追加元素(n个)并返回长度,pop末尾移除(1个)并返回其值
unshift(v)、shift() unshift头部插入元素(n个)并返回长度,shift移除,同上 shift /ʃɪft/ 转移, 改变
copyWithin(i)IE🚫 浅复制数组中的内容,数组内部的复制、粘贴
fill(v,s,e)IE🚫 填充指定的值,arr.fill(value[, start[, end]])
keys()/values() 数组索引、值的迭代器
entries() 数组索引/值对的迭代器
sort() 字符排序,注意是按照字符串比较排序,而不是数字,需传入排序函数 arr1.sort(function(a,b))
reverse() 反转数组项的顺序
concat(arr) 合并并返回新的数组,原数据不变。
slice(start,end?) 截取数组并返回,指定起止位置(不包括结束位置),如无end则到末尾,原数据不变 arr1.slice(2)
splice() 删除、插入和替换:arr.splice(start, deleteCount?,…items?): number[] ,参数items为待插入的数据。 /splaɪs/移接
forEach(func) 数组遍历,参考前文forEach
map(func) 数组遍历执行函数,返回每次函数结果组成的数组 arr.map(function(v,index))
filter(func) 遍历查询,执行查询函数,返回满足过滤条件组成的数组。 arr.filter(function(v,index))
every(func) 遍历是否都满足条件,只有所有项都满足条件,才会返回true arr.every((x,i)=>{return x>3;})
some(func) 遍历是否都存在满足条件,只要有一项满足条件,就会返回true。 arr.some((x,i,arr)=>x>3)
join() 把数组转换成字符串,参数为连接符,默认,
toString() 转换为字符串,逗号,连接
reduce(func) 递归执行函数,语法:reduce((previousValue, currentValue, currentIndex, array) => { },
  1. var arr1=["a","b","c","d"];
  2. console.log(arr1.pop()); //d
  3. console.log(arr1.push("d","e")); //5
  4. arr1 = [13, 24, 51, 3,"6"];
  5. console.log(arr1.sort()); // [13, 24, 3, 51, '6']
  6. function sortN(a,b){
  7. return a-b;
  8. }
  9. console.log(arr1.sort(sortN)); // [3, '6', 13, 24, 51]
  10. var newarr=arr1.concat("7",["a","b"]); //newarr=[3, '6', 13, 24, 51, '7', 'a', 'b']
  11. //splice
  12. var arr=[1,2,3,4];
  13. console.log(arr.splice(0,1)); //[1]

04、Date日期

Date:日期时间对象,创建、获取日期,日期是一个包含年月日时分秒、及相关时间方法的数据对象。Date 时间基于 Unix Time Stamp,即自 1970 年 1 月 1 日(UTC)起经过的毫秒数。

属性/方法 描述 备注
静态属性/方法
Date.now() 获取当期时间的时间戳 Date.now(); //1660059491585
Date.parse(str) 解析日期字符串,并返回时间戳
Date.UTC(year,…) 获取指定年月日时分秒的时间戳,参数同构造函数
构造函数
Date() 创建Date对象的唯一方式,不加new返回的是字符串
- 无参数,当期日期
- 年月日时分秒、毫秒,注意monthIndex从0开始
- Unix 时间戳、字符串
new Date();
Date(); //当期时间的字符串
实例属性/方法
getDate() 获取日,还有获取年、月、日、时、分、秒的对应方法。
setDate(date) 设置日,还有设置年、月、日、时、分、秒的对应方法。
toLocaleString() 返回日期时间的本地格式化字符串 "2022/8/10 10:07:05"
toString() 返回字符串 "Wed Aug 10 2022 10:07:05 GMT+0800 (中国标准时间)"
toLocaleDateString() 返回日期的本地格式化字符串 "2022/8/10"
toLocaleTimeString() 返回时间的本地格式化字符串 "10:07:05"
toJSON() 转字符串,JSON序列化使用 "2022-08-10T02:14:39.138Z"
valueOf() 原始值(时间戳) 1660097530418
  1. const today = new Date();
  2. const birthday = new Date('1995-02-07T03:24:00');
  3. const birthday2 = new Date(1995, 11, 17, 3, 24, 0);
  4. //计算年龄
  5. const v1 = today-birthday; //867998585554 日期相减得到的是时间间隔的毫秒数
  6. const age = Math.floor(v1 /(365*24*60*60*1000)); //27岁

05、Math数学公式

Math 是一个内置对象,拥有一些数学常数属性和数学函数方法。

静态属性/方法 描述 示例
Math.PI 圆周率
Math.random() 随机数,0到1的小数(不含1)
Math.ceil(1.23) 向上取整 Math.ceil(1.23); //2
Math.floor(1.23) 向下取整 Math.floor(1.23); //1
Math.abs(x) 绝对值 Math.abs(-1); //1
Math.max(x1,…xn) 求最大值,对应的Math.min()求最小值
Math.round(x) 取四舍五入的整数
Math.pow(x, y) 计算x的y次方
Math.sqrt(x) 计算平方根

:::warning ❗Math精度:很多 Math 函数都有一个精度,而且这个精度在不同实现中也是不相同的。这意味着不同的浏览器会给出不同的结果,甚至,在不同的系统或架构下,相同的 JS 引擎也会给出不同的结果! :::

06、Maps/Sets带键集合

由Key值标记的键值[key, value]集合容器Map、Set。

类型/属性/方法 描述
Map{[key, value]}IE11 键值对,顺序插入,支持任何类型作为建、值
- 键的相等(零值相等算法):基于===比较,NaN与自身相对,-0、+0相等
Map(…[iterable]?) 构造函数,创建 Map 对象,支持二维数组、可迭代对象,包括其他map(合并map)
size 数量
get(key) 获取键值
set(key,value) 添加/设置键值对
delete(key) 删除键值对
has(key) 判断key是否存在
clear() 清空
keys()/values() 获取键、值的数组
entries() 获取键值[key, value]迭代对象
forEach(func) 执行循环迭代
WeakMap{[key, value]}IE11 弱引用Map,键必须是对象,而值可以是任意的。(Weak /wiːk/ 弱)
- 键(引用对象)被弱保持,没有被其他地方引用,会被GC回收。Key不可枚举
WeakMap() 构造函数,用法类似Map,没有迭代相关方法,无size、clear()
Set{key}IE11 不重复的集合,值相等同Map.Key的零值相等算法
Set(…[iterable]?) 构造函数,创建Set对象
add(obj) 添加值,其他属性方法类似Map
WeakSet{key}IE🚫 弱引用Set,值必须是对象,如果没有被引用会被GC回收,不可枚举

Object与Map、Set的区别


Object Map Set
数据结构 {name:value,...} {key => value, ...} {key1, ...keyN}
默认键值 有一个原型 无-空无一物 无-空无一物
字符串string或symbol 任意类型,有序(插入顺序)
Size 自己计算 size属性获取键值对数量 size
迭代 无迭代协议,不支持for(of),可以用for(in)枚举属性 可迭代 可迭代
性能 一般 键值操作,性能良好
序列化 支持JSON的序列化方法 不支持 不支持
  1. let map = new Map([[1,"N1"],["age",3]]);
  2. map.set(2, "N2");
  3. map.forEach((value,key)=>{ //注意是value在前面
  4. console.log(key+":"+value);
  5. })
  6. console.log(JSON.stringify(map)); //{} 什么都没有
  7. let wset=new Set([1,2,3,"a"]);
  8. wset.forEach((value)=>{
  9. console.log(value);
  10. })
  11. console.log(JSON.stringify(map)); //{} 什么都没有