构造函数和数据常用函数

掌握基于构造函数创建对象,理解实例化过程,掌握对象数组字符数字等类型的常见属性和方法,便捷完成功能。

深入对象

创建对象三种方式

1. 利用对象字面量创建对象

2. 利用 new Object 创建对象

const obj = new Object()
obj.uname = '霍欣标'
console.log(obj)

// 简约的写法
// const obj = new Object({ uname: '霍欣标' })
// console.log(obj)

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

构造函数

构造函数是一种特殊的函数,主要用来初始化对象。

使用场景:常规的{...}语法允许创建一个对象。比如我们创建了佩奇的对象,继续创建乔治的对象还需要重新写一遍,此时可以通过构造函数来快速创建多个类似的对象

构造函数在技术上是常规函数,有两个约定:

  1. 使用new关键字调用函数的行为被称为实例化,实例化就是变成一个对象
  2. 实例化构造函数时没有参数时可以省略()
  3. 构造函数内部无需写return,返回值即为新创建的对象
  4. 构造函数内部的return返回的值无效,所以不要写return
  5. new Object() new Date()也是实例化构造函数
// 构造函数里面想声明一个变量,可以直接用this
function Pink(item) {
  this.arr = 10
  console.log(this.arr)
}
new Pink() // 10
// 创建一个猪 构造函数
function Pig(uname, age) {
  // 新的空对象{}.对象的属性 = 形参
  this.uname = uname
  this.age = age
}
const p = new Pig('佩奇', 6)
console.log(p) // Pig { uname: '佩奇', age: 6 }

// console.log(new Pig('佩奇', 6)) // Pig {uname: '佩奇', age: 6}
// console.log(new Pig('乔治', 3)) //Pig { uname: '乔治', age: 3 }

练习:构造函数创建多个对象

function Goods(name, price, count) {
  this.name = name
  this.price = price
  this.count = count
}
const mi = new Goods('小米', 1999, 20)
console.log(mi) // Goods {name: '小米', price: 1999, count: 20}
const hw = new Goods('华为', 3999, 50)
console.log(hw) // Goods {name: '华为', price: 3999, count: 50}

// 如同时间初始化,系统创建的构建函数,现在我们可以自己创建
const date = new Date('2024-4-8')
console.log(date) // Mon Apr 08 2024 00:00:00 GMT+0800 (中国标准时间)

实例化执行过程

  1. 创建新的空对象
  2. 构造函数this指向新对象
  3. 执行构造函数代码,修改this,添加新的属性
  4. 返回新对象

实例成员

通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员(实例属性和实例方法)

  1. 为构造函数传入参数,创建结构相同但值不同的对象
  2. 构造函数创建的实例对象彼此独立互不影响
// 实例成员和静态成员
// 实例成员:实例对象上的属性和方法属于实例成员
function Pig(name) {
  this.name = name
}
const peiqi = new Pig('佩奇')
const qiaozhi = new Pig('乔治')
peiqi.name = '小猪佩奇'      // 实例属性 (实例成员)
peiqi.sayHi = () => {      // 实例方法 (实例成员)
  console.log('hi~~~')
}
console.log(peiqi === qiaozhi) // false
console.log(peiqi)   // Pig {name: '小猪佩奇', sayHi: ƒ}
console.log(qiaozhi) // Pig {name: '乔治'}

静态成员

构造函数的属性和方法被称为静态成员(静态属性和静态方法)。比如Date.now() Math.Pl Math.random()

  1. 静态成员只能构造函数来访问
  2. 静态方法中的this指向构造函数
// 静态成员 :构造函数上的属性和方法称为静态成员
function Pig(name) {
  this.name = name
}
Pig.eyes = 2 // 静态属性
console.log(Pig.eyes) // 2

Pig.sayHi = function () { // 静态方法
  console.log(this)         // ƒ Pig(name) {this.name = name}
  console.log('学到就要教人') // 学到就要教人
}
Pig.sayHi()

实例对象的属性和方法即实例成员,实例对象相互独立,实例成员当前实例对象使用。

内置构造函数

在JavaScript中最主要的数据类型有六种:基本数据类型——字符串 数值 布尔 undefined null ; 引用类型——对象,但是,我们会发现有些特殊情况:

其实字符串、数值、布尔、等基本类型也都有专门的构造函数,这些我们称为包装类型。JS中几乎所有的数据都可以基于构成函数创建。

const str = '欣标'
console.log(str.length) // 2

const num = 12
console.log(num.toFixed(2)) // 12.00

// 等同于下面(底层完成) 内部执行:把简单数据类型包装为了引用数据类型
// 1.普通类型实例化,把欣标字符串包装成一个对象,然后就可以调用方法
const str = new String('欣标')

Object

引用数据类型:Object Array RegExp Date等。

包装数据类型:String Number Boolean 等。

Object 是内置的构造函数,用于创建普通对象。推荐使用字面量方式声明对象,而不是Object构造函数

学习三个常用静态方法(静态方法就是只有构造函数Object可以调用的)

经常使用的场景给对象添加属性

const o = { uname: 'xinbiao', age: 18 }
// 1. 获得所有的属性名
console.log(Object.keys(o))  // 返回一个数组 ['uname', 'age']
// 2. 获得所有的属性值
console.log(Object.values(o)) //返回一个数组 ['xinbiao', 18]

// 3. 对象拷贝
const oo = {}
// 对象方法(拷贝位置,拷贝数据)
Object.assign(oo, o)
console.log(oo) // {uname: 'xinbiao', age: 18}

// 使用的场景给对象添加属性
Object.assign(o, { gender: '男' })
console.log(o) // { uname: 'xinbiao', age: 18, gender: '男' }

Array

Array是内置的构造函数,用于创建数组,创建数组建议使用字面量创建,不用Array构造函数创建

数组常见核心实例方法

方法 作用 说明
forEach 遍历数组 不返回数组,经常用于查找遍历数组元素
filter 过滤数组 返回新数组,返回的是筛选满足条件的数组元素
map 迭代数组 返回新数组,返回的是处理之后的数组元素,想要使用返回的新数组
reduce 累计器 返回累计处理的结果,经常用于求和等

reduce返回累计处理的结果,经常用于求和等。如果有起始值,则把初始值累加到里面。

// 数组reduce 方法
const arr = [1, 2, 3, 4]

// 1.没有初始值
// arr.reduce(function(上一次值,当前值){},初始值)
const total = arr.reduce(function (prev, current) {
  return prev + current
})
console.log(total) // 10

// 2.有初始值
const total = arr.reduce(function (prev, current) {
  return prev + current
}, 10) // 初始值(对应上一次值)是10 + prev + current
console.log(total) // 20

// 3.箭头函数
const total = arr.reduce((prev, current) => prev + current, 10)
console.log(total) // 20

reduce执行过程

  1. 如果没有起始值,则上一次值以数组的第一个数组元素的值
  2. 每一次循环,把返回值给做为下一次循环的上一次值
  3. 如果有起始值,则起始值做为上一次值
// 没有初始值
const arr = [1, 3, 8]
arr.reduce((prev, current) => prev + current)
// 上一次值 当前值 返回值(第一次循环)
//   1      3      4
// 上一次值 当前值 返回值(第二次循环)
//   4      8     12

// 有初始值
const arr = [1, 3, 8]
arr.reduce((prev, current) => prev + current, 10)
// 上一次值 当前值 返回值(第一次循环)
//   10      1     11
// 上一次值 当前值 返回值(第二次循环)
//   11      3     13
// 上一次值 当前值 返回值(第三次循环)
//   13      8     21

练习:计算薪资

根据数据计算当月支出薪资

const arr = [{
  name: '张三',
  salary: 10000
}, {
  name: '李四',
  salary: 10000
}, {
  name: '王五',
  salary: 20000
},
]

// 1. 需求:计算薪资案例
// 来声明常量 = arr.reduce(( 数组 , 对象 ))
const total = arr.reduce((prev, current) => {
  console.log(prev)
  return prev + current.salary // 对象.价格
}, 0) // [{ }]初始值千万不能省
console.log(total) // 40000

// 2. 需求:每个人涨新30%,当月支出多少新资
const total = arr.reduce((prev, current) => prev + current.salary * 1.3, 0)
console.log(total) // 52000

数组常见其他实例方法

实例方法 说明
join 数组元素拼接为字符串,返回字符串
find 查找元素,返回符合测试条件的第一个数组元素值,若没有符合条件的则返回undefined
every 检测数组所有元素是否都符合指定条件,若所有元素都通过检测返回true,否则返回false
some 检测数组中的元素是否满足指定条件,若数组中有元素满足条件返回true,否则返回 false
concat 合并两个数组,返回生成新数组
sort 对原数组单元值排序
splice 删除或替换原数组单元
reverse 反转数组
findIndex 查找元素的索引值

更多数组方法:mdn web docs Array

find 数组查找

数组套对象的数据,查找某一个数组对象值并返回这个对象。

// 查找元素
// const arr = ['red', 'blue', 'green']
// const re = arr.find(function (item) {
//   return item === 'blue'
// })
// console.log(re) // blue

const arr = [
  {
    name: '小米',
    print: 1999
  },
  {
    name: '华为',
    print: 3999
  },
]

// 找小米 把这个对象,并且返回这个对象
const mi = arr.find(function (item) {
  // console.log(item)       // 数组元素
  // console.log(item.name) // 数组元素里 name
  // console.log(11)       // 循环查找
  return item.name === '小米' // 数组元素.name === 小米 就返回小米这个对象
})

console.log(mi) // {name: '小米', print: 1999}

// 简化箭头函数
const mi = arr.find(item => item.name === '小米')
console.log(mi) // {name: '小米', print: 1999}

eveny检查数组每一条数据

// every每一个是否都符合条件,如果都符合返回true,否则返回false
const arr = [10, 20, 30]
const flag = arr.every(item => item >= 10)
console.log(flag) // true

const arr1 = [9, 20, 30]
const flag1 = arr1.every(item => item >= 10)
console.log(flag1) // false

some检查符合一个值

// some方法数组中只有一个值符合条件,如果符合返回true,否则返回false
const arr2 = [3, 5, 30]
const flag = arr2.some(item => item >= 10)
console.log(flag) // true

练习:选购界面的数据处理

const spec = { size: '40cm*40cm', color: '黑色' }sizecolor里面的值拼接为字符串之后,写到div标签里面,展示内容如:40cm*40cm/黑色

思路:获得所有的属性值,然后拼接字符串就可以了

  1. 获得所有属性值是: Object.values()返回的是数组
  2. 拼接数组是join("")这样就可以转换为字符串了
const spec = { size: '40cm*40cm', color: '黑色' }
// 1. 所有的属性值回去过来  数组
// console.log(Object.values(spec))
// 2. 转换为字符串   数组join('/') 把数组根据分隔符转换为字符串
// console.log(Object.values(spec).join('/'))
document.querySelector('div').innerHTML = Object.values(spec).join('/')

数组方法:伪数组转换为真数组

如果提示控制台Uncaught TypeError: lis.pop is not a function ,这说明lis 不是一个真数组。

// Array.from 把伪数组转换为真数组
const lis = document.querySelectorAll('ul li')
// console.log(lis)
// lis.pop() 删除 报错
const liss = Array.from(lis) // 伪数组转换为真数组
liss.pop()
console.log(liss) // [li li]

String

在字符串中,一个中文汉字、一个英文字母、一个标点符号和一个空格都算是一个索引号,默认从0开始。

String常见实例方法

实例方法使用说明
length用来获取字符串的度长(重点)
split用来将字符串拆分成数组(重点)
substring用于字符串截取(重点)
startswith检测是否以某字符开头(重点)
includes判断一个字符串是否包含在另一个字符串中,根据情况返回truefalse(重点)
toUpperCase用于将字母转换成大写
toLowerCase用于将就转换成小写
indexOf检测是否包含某字符
endswith检测是否以某字符结尾
replace用于替换字符串,支持正则匹配
match用于查找字符串,支持正则匹配

split字符串转换数组

// 把字符串转换为数组, 与join相反
const str = 'pink,red'
const arr = str.split(',')
console.log(arr) // ['pink', 'red']

const str1 = '2024-4-8'
const arr1 = str1.split('-')
console.log(arr1) // ['2024', '4', '8']

const str3 = '180cm/58kg/黑色'
const arr3 = str3.split('/')
console.log(arr3) // ['180cm', '58kg', '黑色']

substring字符串截取

需要截取的第一个字符的索引,该索引位置的字符作为返回的字符串的首字母

// 字符串截取 substring((开始索引号,结束索引号))
// 如果省略索引号,则取到最后
// 结束的索引号不包含截取的部分
const str = '今天又要去上班了'
console.log(str.substring(5)) // 上班了
console.log(str.substring(5, 7)) // 上班

startswith检测某字符开头

startswith来判断当前字符串是否以另外一个给定的子字符串开头,并根据判断返回truefalse

// startsWith 判断是不是以某个字符开头
const str = 'xinbiao 今天又要去上班了'
console.log(str.startsWith('xinbiao')) // true
console.log(str.startsWith('xin')) // true
console.log(str.startsWith('欣标')) // false

endsWith检测某字符结束

// endsWith 判断是不是以某个字符结尾
const str = '欣标今天又要去上班'
console.log(str.endsWith('上班')) // true
console.log(str.endsWith('要去')) // false

includes检测字符串包含

用于判断一个字符串是否包含在另一个字符串中,根据情况返回truefalse

// includes 字符串是否包含检索词
const str = '我是霍欣标的小艺'
console.log(str.includes('霍欣标')) // true
console.log(str.includes('霍欣标', 2)) // true
console.log(str.includes('霍欣标', 3)) // false

练习:显示赠品

字符串渲染到准备好的p标签内部,结构必须如左下图所示,展示效果如引用所示:

【赠品】50g茶叶
【赠品】清洗球

  1. 把字符串拆分为数组,这样两个赠品就拆分开了,用split
  2. 利用map遍历数组,同时把数组元素生成到span里面,并且返回
  3. 因为返回的是数组,所以需要 转换为字符串,用join
const gift = '50g的茶叶,清洗球'

// 1. 把字符串拆分为数组
// console.log(gift.split(',')) // ['50g的茶叶', '清洗球']

// 2. 根据数组元素的个数,生成对应span标签
// const str = gift.split(',').map(function (item) {
//   return `<span>【赠品】 ${item}</span> <br>`
// }).join('')
// console.log(str)
// document.querySelector('div').innerHTML = str

// 简化语法
document.querySelector('div').innerHTML = gift.split(',').map(item => `<span>【赠品】 ${item}</span> <br>`).join('')

Number

toFixed保留小数位

Number是内置的构造函数,用于创建数值。

常用方法:toFixed()设置保留小数位的长度,保留两位小数,四舍五入

const num = 10.923
console.log(num.toFixed()) // 11
console.log(num.toFixed(1)) // 10.9
console.log(num.toFixed(2)) // 10.92

const num1 = 10
console.log(num1.toFixed()) // 10
console.log(num1.toFixed(1)) // 10.0
console.log(num1.toFixed(2)) // 10.00

转换为字符串

const num = 10
// 强制转换
console.log(String(num))    // 10
// 方法转换
console.log(num.toString()) // 10

Element.remove()

Element 是最通用的基类,Document 中的所有元素对象(即表示元素的对象)都继承自它。它只具有各种元素共有的方法和属性。更具体的类则继承自 Element

Element.remove() 方法,把对象从它所属的 DOM 树中删除。 Demo

const div = document.querySelector('div')
div.addEventListener('click', function () {
  div.remove()
})

综合案例:购物车展示

分析业务模块:Demo

  1. 根据数据渲染页面
    • 先利用map来遍历,有多少条数据,渲染多少相同商品
    • 注意map返回值是数组,我们需要用join转换为字符串
    • 把返回的字符串 赋值 给list大盒子的innerHTML
  2. 更换数据
    • 2.1 更换不需要处理的数据,图片,商品名称,单价,数量
      • 采取对象解构的方式
      • 注意单价要保留2位小数,489.00toFixed(2)
    • 2.2 更换规格文字模块
      • 获取每个对象里面的spec,上面对象解构添加spec
      • 获得所有属性值是 Object.values()返回的是数组
      • 拼接数组是join('')这样就可以转换为字符串了
    • 2.3 更换赠品模块
      • 获取 每个对象里面的gift,上面对象解构添加gift
      • 思路:
        • 把字符串拆分为数组,这样两个赠品就拆分开了用split('')方法
        • 利用map遍历数组,同时把数组元素生成到span里面,并且返回
        • 因为返回的是数组,所以需要 转换为字符串,用join('')方法
      • 注意判断是否有gif属性,没有的话不需要渲染利用变成的字符串然后写到p.name里面
  3. 总价模块
    • 更换小计模块
      • 小计 = 单价 * 数量
      • 小计名可以为subTotal = price * count
      • 注意保留2位小数
      • 小数计算精度问题,经常转换为整数:(0.1 * 100 + 0.2 * 100) /100 === 0.3
    • 更换合计模块
      • 求和用到数组reduce方法累计器
      • 根据数据里面的数量和单价累加和即可
      • 注意reduce方法有2个参数,第一个是回调函数,第二个是初始值,这里写0
const goodsList = [
  {
    id: '4001172',
    name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
    price: 289.9,
    picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
    count: 2,
    spec: { color: '白色' }
  },
  {
    id: '4001009',
    name: '竹制干泡茶盘正方形沥水茶台品茶盘',
    price: 109.8,
    picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
    count: 3,
    spec: { size: '40cm*40cm', color: '黑色' }
  },
  {
    id: '4001874',
    name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
    price: 488,
    picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
    count: 1,
    spec: { color: '青色', sum: '一大四小' }
  },
  {
    id: '4001649',
    name: '大师监制龙泉青瓷茶叶罐',
    price: 139,
    picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
    count: 1,
    spec: { size: '小号', color: '紫色' },
    gift: '50g茶叶,清洗球,宝马,奔驰'
  }
]

// 1. 根据数据渲染页面
document.querySelector('.list').innerHTML = goodsList.map(item => {
  // console.log(item) // 每一条对象
  // 对象解构
  const { picture, name, count, price, spec, gift } = item
  // 2.2 更换规格文字模块
  const text = Object.values(spec).join('/')
  // 2.3 处理赠品模块
  const str = gift ? gift.split(',').map(item => `<span class="tag">【赠品】${item}</span>`).join('') : ''
  // 3.计算小计模块 单价 * 数量
  // 注意精度问题,因为保留两位小数,所以乘以100 最后除以100
  const sbuTotal = ((price * 100 * count) / 100).toFixed(2)
  return `
    <div class="item">
      <img src=${picture} alt="">
      <p class="name">${name} ${str}</p>
      <p class="spec">${text}</p>
      <p class="price">${price.toFixed(2)}</p>
      <p class="count">x${count}</p>
      <p class="sub-total">${sbuTotal}</p>
    </div>
  `
}).join('')

// 3.合计模块
const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0)
document.querySelector('.amount').innerHTML = total.toFixed(2)

原创文章,作者:霍欣标,如若转载,请注明出处:https://www.bigengwu.cn/xue/148.html

霍欣标的头像霍欣标
上一篇 2024-09-06 21:52
下一篇 2024-09-18 21:38

相关推荐

博主人懒,应管局要求暂不开启站内私信和评论功能,如需帮助请发邮件。

邮箱账号:1969600480@qq.com