javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > js 数组对象字符串

JS数组、对象、字符串与部分新属性实例详解

作者:AAA 我不会前端开发

文章主要介绍了JavaScript中数组、对象、字符串、Symbol、Set、WeakSet、Map和WeakMap等数据结构和方法的使用,涵盖了声明、操作、迭代器、解构赋值等各个方面,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

一:数组,对象 部分常见方法可以去构造函数部分查看

(1) 数组

数组本质就是一个对象 所以对于一些对象的方法 数组也可以去使用 通过检查数组的类型就会发现数组的类型就是Object

数组的声明方法:

let arr = [1, 2, 3, 4, 5]
let arr1 = new Array(1, 2, 3, 4, 5)//构造函数式声明

数组常用方法:

let arr = [1, 2, 3];
//数组的赋值操作
arr[0] = 1
//将元素添加到数组的尾部 并返回数组的长度
arr.push(4);
//弹出数组末尾元素
arr.pop();
//添加新内容到数组开头 并且返回数组的长度
arr.unshift(0)
//arr.shift 删除第一个元素 
arr.shift()
//arr.splice(起始位置,删除几个元素)
arr.splice(1, 1)
//遍历数组
arr.forEach(item => console.log(item));
//fill填充数组
arr=[];
arr.fill(1) //将数组全部填充为1
//copyWithin复制数组的元素
let hhh=[1,2,3,4,5,6,7,8]
console.log(hhh.copyWithin(4,1,3));//(要粘贴的位置,复制目标的起始位置,复制目标的结束位置(不包括该位置))

常用方法:

pushpopshiftunshiftslicesplicemapfilterreduce

数组解构赋值:

//数组解构 将单元直批量赋值给变量的语法  本质是把数组元素赋值给变量
const arr=[100,60,80]
const [max,min,avg]=arr
console.log(max)//100
//交换两个变量
let a=1
let b=0;
[b,a]=[a,b]
console.log(a,b);//1
//剩余参数解决 参数多 变量少问题
const [c,d,...arrr]=[1,2,3,4,5]
console.log(arrr);
//按需解构赋值
const [e,f,,r]=[1,3,4,5]
console.log(r);//5
//多维数组解构
const arr1=[[1,2,3],1]
console.log(arr1[0][0]);// 1
const [t,y]=arr1

数组的查找方法

数组的查找方法和字符串的查找是一样的 可以理解为字符串本事就是一个字符数组 注意startsWithendsWith方法不能使用

一些列用于检索的数组方法 const hd=['h','e','i','m','a','c','h','e','g','n','x','v','y','a','u','n']提前定义字符串

console.log(hd.indexOf('d'));//返回检索字符所在的位置 找不到的返回负一 从左边开始查找
console.log(hd.includes('h',8));//返回布尔类型 可以设置第二个参数从指定位置开始查找
console.log(hd.lastIndexOf('o'));//从最右边向左开始查找

数组的迭代器

1.什么是迭代器

迭代器是js中一种特殊的对象,它允许我们按顺序访问数组中的元素,这个迭代器对象是按照迭代器协议创建的next()方法 该方法要求返回一个钓鱼两个属性的对象: value属性(当前迭代的值) done属性(布尔值 表示迭代的状态 是否完成)

2.理解迭代器

可以理解迭代器为一个智能的指针,他知道当前指向哪个元素(value)并且知道当前迭代有没有完成(done)。

3.简单使用迭代器

迭代器工作原理

const arr = [1, 2, 3];
// 获取数组的迭代器对象
let iterator = arr.values(); 
// 使用迭代器逐个访问元素
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

利用迭代器包装的方法

const arr = [1, 2, 3];
// values() - 返回值的迭代器
for (let value of arr.values()) {
  console.log(value); // 1, 2, 3
}
// keys() - 返回索引的迭代器
for (let key of arr.keys()) {
  console.log(key); // 0, 1, 2
}
// entries() - 返回索引和值的迭代器
for (let [key, value] of arr.entries()) {
  console.log(key, value); // 0 1, 1 2, 2 3
}

4.迭代器的特点

(2) 对象

声明对象

1.字面量直接创建

let person = {
  name: 'Tom',
  age: 18,
  sayHi() {
    console.log('Hi, I am ' + this.name);
  }
}
console.log(person.name);
person.sayHi();

2.利用js内置方法构造对象

//2.new一个对象创建的是一个空对象   
  const obj2=new Object({name:2})

3.利用构造函数创建对象

构造函数的本质:任何函数都可以作为构造函数,通过 new 关键字调用

//构造函数是一种特殊的函数 作用是用来初始化对象的
    function Friden(name,age) {//第一个字母一定是大写开头 只能通过new执行
      this.name=name
      this.age=age
    }
    const yuxuan=new Friden('yuxuan',18)//new的过程就是实例化
    console.log(yuxuan);

关于使用构造函数创建对象的一些问题

为什么能使用构造函数比如Friden()直接new 一个对象呢,当我们使用 new 关键字调用构造函数时,JavaScript 引擎会创建一个新对象,而构造函数内部使用的 this 就指向这个新创建的对象。因此,在构造函数中通过 this.xxx = xxx 设置的属性确实是直接挂载到这个新对象上的。这个过程在ES6中被直接简化成了语法糖Calss的形势

//使用Class语法糖 是基于原型的构造函数机制
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, I'm ${this.name}`);
  }
}
//本质上是一样的是 基于原型的构造函数机制 、
function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.sayHello = function() {
  console.log(`Hello, I'm ${this.name}`);
};

4.实例属性与静态属性

实例属性:

function Pig(name){
  this.name = name;  // 实例属性
}
const peiqi = new Pig('peiqi');
// name 属性属于实例对象,每个实例都有自己独立的副本

实例成员

静态属性:

静态成员

function Person(name) {
  this.name = name;
}
Person.eyes = 2;  // 静态属性
Person.arms = 2;  // 静态属性
// 这些属性直接添加到构造函数本身,而不是实例对象

原型链关系

对象的基本使用:

let phone = {
      "goods-name": `xiaomi14`,
      money: 4000,
      address: `中国`
    }	
//查找对象的属性
    document.write(phone.address)
    //修改对象属性
    phone.name = `xiaomi15`
    document.write(phone.name)
    //增加对象属性
    phone.color = `白色`
    document.write(phone.color)
    //删除对象属性
    delete phone.money//和c++很像
    document.write(phone.money)//打印是undefind
	//查找对对象
	console.log(phone["goods-name"])
	console.log(phone.money);
	//遍历对象与数组
	for (let key in game) {//key是变量名可以随便取 但是要和后面的game[key]对应
      console.log(game[key])
    }//此方法也可以遍历数组
    let arr = [1, 2, 3, 4, 5]
    for (let k in arr) {
      console.log(arr[k])
    }

对象的解构赋值:

//解构时属性名和对象名相同
 const{uanme,age}={uanme:'你好',age:18}
 console.log(uanme);
//对象解构变量名更改
const{uanme:username,age:age1}={uanme:'你好',age:19} 
//解构数组对象
const pig =[{uname:'佩奇',age:6}]
const[{uname,age}]=pig 
// 多级对象解构
const pig={
  name:'pigs',
  family:{
    mother:'mama',
    father:'baba'
  },
  age:6
}
const {name,family:{mother,father},age}=pig

二:  字符串与新增属性

(1) 字符串

1. 字符串转义符

转义符: “ \ ” 后面没跟需要转义的字符

" 这中间是"一个分号 " 如果我们想打印出这个字符串 中间存在一个“ 这就导致不能直接打印出这串字符 这时候需要使用转义符号

let str="我是一个 \" 分号"
console.log(str);

2. 字符串拼接与模板字符串,截取,替换

(1)字符串的拼接

拼接字符可以使用+来拼接左右两个字符,或者使用模板字符串。

let obj=[{title:'1'},{title:'2'},{title:'3'}]
function title(){
 return `${
  obj.map((item)=>{
    return `<li>`+item.title+`</li>`
  }).join('')
 }`
}
function title2(){
  return `${obj.map((item)=>{
    return `<li>${item.title}</li>`
  }).join('')}`
}
// 两种写法

(2)字符串的截取

let hd='heimachegnxvyaun'

字符串的截取有三个方法

hd.slice(-3,-1)
hd.slice(0)
hd.slice(0,3)
hd.substr(0)
hd.substr(0,3)
hd.substring(0)
hd.substring(0,3)
hd.substring(-3,6)

3. 标签模版

其实就是一个函数 但是存在两个参数 一个是字符串 一个是一个数组

字符串存储的是未填充的字符串 数组存储的是填充的值

function tag(String,...vars){
  // vars 接收所有插值变量组成的数组  所以前一个String是用来存储要被输出的字符串的 然后字符串里面的插入值存在vars里面
  console.log(vars);  // 输出: ["houdenren.com", "后盾人"]
  // String 接收模板字符串被插值分割后的部分
  console.log(String); // 输出: ["在线编程网", ",作者", ""]
}
let uname='后盾人'
let web ='houdenren.com'
tag(`在线编程网${web},作者${uname}`);
// 其实主要的作用是对标签中的变量或者字符进行二次处理

4. 字符串检索

一些列用于在字符串中做检索的字符串方法 const hd='houdunren'提前定义字符串

console.log(hd.indexOf('d'));//返回检索字符所在的位置 找不到的返回负一 从左边开始查找
console.log(hd.includes('h',8));//返回布尔类型 可以设置第二个参数从指定位置开始查找
console.log(hd.lastIndexOf('o'));//从最右边向左开始查找
console.log(hd.startsWith('h'));//判断字符串起始值 
console.log(hd.endsWith('h'));//判断字符串结束符

(2)Symbol

Symbol 是 ES6 引入的一种新的原始数据类型,主要用于创建唯一的标识符。可以作为一些属性名的标识符,比如为对象添加唯一的属性名,也可以对属性进行私有化 不让外部来遍历该属性. 可以有效避免属性重名的问题

特点:

  1. 唯一性:每个 Symbol 值都是唯一的,即使使用相同的描述创建
  2. 隐藏性Symbol 属性不会出现在常规的遍历中(如 for...in 或 Object.keys)
  3. 不可枚举Symbol 属性默认不可枚举,不会被 JSON.stringify() 序列化
let symbol = Symbol();
let obj = {
  name: "李四",
  [symbol]: "张三",
};
// 普通遍历遍历不到 symbol 属性
for (let key in obj) {
  console.log(key); //name
}
// 通过for of Reflect.ownKeys()可以遍历到对象里面的 symbol 属性
for (let key of Reflect.ownKeys(obj)) {
  console.log(key);//name Symbol()
}

属性私有化:

let site = Symbol();
class User {
  constructor(name) {
    this.name = name;
    this[site] = "houdunren";
  }
  getName() {
    return `${this.name} ${this[site]}`;
  }
}
let newuser=new User("lisi")
console.log(newuser.getName()); //lisi houdunren
// 不能获取到symbol属性
for (let key in newuser) {
  console.log(newuser[key]); // lisi
}

基本用法:

声明symbol变量 访问的时候需要使用symbol变量的description属性来访问

// 创建 Symbol
let yf = Symbol("我是逸飞");
console.log(yf); // Symbol(我是逸飞)
console.log(yf.description); // 提取Symbol的描述
// 全局共享的 Symbol
let gs1 = Symbol.for('global');
let gs2 = Symbol.for('global');
console.log(gs1 === gs2); // true

(3)Set与__WeakSet__

set:

set是一个集合数据类型 和数组相似 但是set中不能存在重复的数据 本质和数组一样是一个引用类型的数据结构

set列表定义及其常见方法:

// set是一个集合数据类型 和数组很类似 但是set中不能含有重复的数据
let set =new Set([1,2,3,4,5])
set.add(1);
set.add(1);
set.add(1);
console.log(set);
// 如果定义的时候 set里面是字符串就会把字符串的个字符当作元素
let sets=new Set("hdcms")
console.log(sets);//Set(5) { 'h', 'd', 'c', 'm', 's' }
//增
set.add(1);
set.add(2);
//删
// 单个删除
set.delete(1);
// 清空全部
// set.clear();
// 查询方法
// 查询set里面的元素个数
console.log(set.size); // 2
// 展开语法查看set
console.log([...set]); // [1,2]
// 判断某个元素是否存在,返回布尔类型
console.log(set.has(1)); // true

set的遍历

let set=new Set([1,2,3,4,5,6])
set.forEach(function(value,index,set){//使用forEach遍历set
  console.log(value);
})
for (const value of set) {//使用forof遍历set
  console.log(value);
}

weakset:

weakset和set类型一样都是只能存储唯一值的列表 区别就是weakset是一个弱引用类型的数据结构,并且weakset不能够遍历,并且weakset只能存储对象引用,不能存储基本类型值.

什么是弱引用:

先观察一下set与weakset的区别

不难理解出 弱引用就是不用阻止垃圾回收器去回收被weakset引用的对象

如果我们定义一个对象a 分别用不同的变量去引用a 每一次引用都会标记一次引用次数 但是用weakset去引用这个对象就不会添加引用次数 当变量都被清除之后对象a的引用次数也会归零 weakset不会阻止a被垃圾回收

使用示例

let nodes=new WeakSet()
let divs=[{div:1},{div:2}]
divs.forEach(element => {
nodes.add(element)
});
console.log(nodes);
//删除 
nodes.delete(divs[0])
console.log(nodes);
//同样使用has判断元素是否存在
console.log(nodes.has(divs[1]));
//weakset不可遍历 并且只能储存对象

(4)Map与weakMap

Map:

简单理解map

map就是键值对的集合 可以近似理解为用键名代替数组索引的类数组

map类型和obj类型的区别:对象的键只能是字符串类型,map的键名可以是各种类型

声明Map:

// 声明Map类型
let map = new Map();
// 键名为字符串 Map方法添加数据不是添加 叫设置数据
map.set("name", "李四");
// 键名为数字
map.set(1, "数字");
// 键名为方法
map.set(function() {}, "方法作为键名");
// 对象键名
map.set({}, "对象键名");
console.log(map);
//或者直接来定义
let map2=new Map([[{},"对象"],[[],'数组'],[function(){},'函数']])
console.log(map2);

Map的增删改查

let map = new Map();
// 增
map.set('name','张三')
map.set('age',18)
// 删除
// 单个删除,返回布尔值
console.log(map.delete('age'));
// 全部删除,没有返回值
// map.clear()
// 查询
console.log(map.get('name'));

遍历Map变量:

let map = new Map();
map.set("name", "李四");
map.set("age", "15");
// 遍历所有的key
console.log(map.keys());//返回所有的键
// 返回所有的值
console.log(map.values());
// 返回值和键
console.log(map.entries());
// for of 遍历键名
for (let key of map.keys()) {
  console.log(key);
}
// for of 遍历值
for (let val of map.values()) {
  console.log(val);
}
// 对象同时接收键和值
for (let [key, val] of map.entries()) {
  console.log(key, val);
}
// forEach 遍历 map,第一个值是键值,第二个值是键名
map.forEach((item, key) => {
  console.log(item, key);
});

将Map类型转换为数组:

map虽然作为键值对的集合,也可以将键和值单独转换成两个单独的数组 使用展开语法配合不同的方法即可

let hd=new Map([['中文','chinese'],['nihao','hello']])
console.log([...hd]);//将键值对转化为二维数组
console.log([...hd.keys()]);//单独转换键
console.log([...hd.entries()]);//将键值对转化为数组
console.log([...hd.values()]);//将值转化为数组
let newhd=[...hd].filter((item)=>{
  return item[1].includes('chinese')
})
console.log(newhd);

WeakMap:

WeakMapMap基本类似,不一样的是WeakMap的键只能是对象,而且不会增加对象的引用. 和WeakSet一样 WeakMap不能遍历 没有size属性 不能cleat直接清除 不能使用foreach方法

常见的使用

验证弱引用特性

let obj={
  name:'list'
}
let weakmap=new WeakMap();
weakmap.set(obj,'houdunren')
// 验证WeakMap中是否有这个键
console.log(weakmap.has(obj));  // 会输出 true
// 获取值
console.log(weakmap.get(obj));  // 会输出 'houdunren'
obj = null;
console.log(weakmap);
setTimeout(() => {
  // 倒计时一秒后再打印结果为空
  console.log(weakmap);
}, 1000);

到此这篇关于JS数组、对象、字符串与部分新属性实例详解的文章就介绍到这了,更多相关js 数组对象字符串内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文