Pink老师JS进阶DAY2学习记录-构造函数
一. 构造函数
可以通过构造函数来快速创建多个类似的对象
1. 怎么用
function Goods(name, price, count){
this.name = name
this.price = price
this. count = count
// 不需要写return,返回值是对象
}
const xiaoMi = new Goods('小米', 1999, 20) // 实例化
const huaWei = new Goods('华为', 3999, 59) // 实例对象彼此独立互不影响
const vivo = new Goods('vivo', 1888, 200)
console.log(xiaoMi)
console.log(huaWei)
console.log(vivo)
2. new实例化执行过程
a. 创建一个新的空对象
b. 构造函数this指向新对象
c. 执行构造函数代码,修改this,添加新的属性
d. 返回新对象
3. 实例成员和静态成员
a. 通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员。
const peppa = Pig('佩奇' , 20)
console.log(peppa.name) // 访问实例属性(实例成员)
peppa.sayHi() // 调用实例方法(实例成员)
b. js允许直接为函数动态添加属性或方法,构造函数的属性和方法称为静态成员
一般公共特征的属性或方法设置成静态成员
function Person(name, age){
// 省略实例成员
}
// 静态属性(静态成员)
Person.eyes = 2
Person.arms = 2
// 静态方法(静态成员)
Person.walk = function() {
console.log('人人都会走路')
console.log(this.eyes) // this指向Person,构造函数本身
}
5. 基本包装类型
一般引用数据类型才有方法,但是我们发现基本数据类型也有,例如str.length
,num.toFixed(2)
。这是因为js底层把简单数据类型包装成了引用数据类型。
其实字符串,数值,布尔等基本数据类型也都有专门的构造函数,这些称之为包装类型。
二. 内置构造函数
1. Object
三个常用的静态方法(静态方法也就是只有构造函数Object可以调用)
Object.keys()
Object.values()
Object.assign()
const o = { name: '佩奇', age: 6}
const obj = {}
// 1. 获取所有属性名
console.log(Object.keys(o)) // ['name', 'age']
// 2. 获取所有属性值
console.log(Object.values(o)) // ['佩奇', '6']
// 3. 对象的拷贝
Object.assign(obj, o) // o拷贝给obj
Object.assign(o, {gender: '女'}) // 追加性别属性给对象o
2. Array
a. 实例方法
1.之前学过的forEach,filter,map
2.总结:(只掌握重点)
-
推荐使用字面量方式声明数组,而不是
Array
构造函数 -
实例方法
forEach
用于遍历数组,替代for
循环 (重点) -
实例方法
filter
过滤数组单元值,生成新数组 (重点) -
实例方法
map
迭代原数组,生成新数组 (重点) -
实例方法
reduce
累计方法,返回和 (重点) -
实例方法
join
数组元素拼接为字符串,返回字符串 (重点) -
实例方法
find
查找元素, 返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined (重点) -
实例方法
every
检测数组所有元素是否都符合指定条件,如果所有元素都通过检测返回 true,否则返回 false (重点) -
实例方法
some
检测数组中的元素是否满足指定条件 如果数组中有元素满足条件返回 true,否则返回 false -
实例方法
concat
合并两个数组,返回生成新数组 -
实例方法
sort
对原数组单元值排序 -
实例方法
splice
删除或替换原数组单元 -
实例方法
reverse
反转数组 -
实例方法
findIndex
查找元素的索引值
3.arr.reduce()
累计方法(一般用于数组求和)
语法:arr.reduce(fuction(前一个值, 当前值){ }, 初始值)
,每一次循环返回当前累计的和
怎么用:
const arr = [1, 5, 9]
// const count = arr.reduce(function(prev, item){
// return prev + item
//}, 0) // 初始值为0,这里可以省略
const count = arr.reduce((prev, item) => prev + item) // 箭头函数写法
// 执行过程如下
// 前一个值 当前值 返回值
// 1 5 6 (第一轮)
// 6 9 15 (第二轮)
// 初始值为0时,第一轮的前一个值为数组第一个值,有初始值时,第一轮的前一个值就为初始值
小小案例(涨薪):
const arr = [{
name: '张三',
salary: 10000
}, {
name: '李四',
salary: 10000
}, {
name: '王五',
salary: 20000
},
]
const money = arr.reduce((prev, item) => prev + item.salary * 0.3, 0)
console.log(money)
这里必须要有初始值,因为数组第一个元素是一个对象,第一轮循环的前一个值就为0,之后的item都是 对象.salary
4.小小综合案例(商品页面勾选的信息,显示到购物车里)
数据:
需求:(获取属性值再拼接字符串即可)
代码:
<script>
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('/')
</script>
b. 静态方法
Array.from
伪数组转换为真数组
// Array.from(lis) 把伪数组转换为真数组
const lis = document.querySelectorAll('ul li')
// console.log(lis)
// lis.pop() 报错
const liss = Array.from(lis)
liss.pop()
console.log(liss) // 只有俩小li
3. String
总结:
- 实例属性
length
用来获取字符串的度长(重点) - 实例方法
split('分隔符')
用来将字符串拆分成数组(重点) - 实例方法
substring(需要截取的第一个字符的索引[,结束的索引号])
用于字符串截取(重点) - 实例方法
startsWith(检测字符串[, 检测位置索引号])
检测是否以某字符开头(重点) - 实例方法
includes(搜索的字符串[, 检测位置索引号])
判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false(重点) - 实例方法
toUpperCase
用于将字母转换成大写 - 实例方法
toLowerCase
用于将就转换成小写 - 实例方法
indexOf
检测是否包含某字符 - 实例方法
endsWith
检测是否以某字符结尾 - 实例方法
replace
用于替换字符串,支持正则匹配 - 实例方法
match
用于查找字符串,支持正则匹配
<script>
//1. split 把字符串 转换为 数组 和 join() 相反
// const str = 'pink,red'
// const arr = str.split(',')
// console.log(arr) // ['pink', 'red']
// const str1 = '2022-4-8'
// const arr1 = str1.split('-')
// console.log(arr1)// [2021, 4, 8]
// 2. 字符串的截取 substring(开始的索引号[, 结束的索引号])
// 2.1 如果省略 结束的索引号,默认取到最后
// 2.2 结束的索引号不包含想要截取的部分
// const str = '今天又要做核酸了'
// console.log(str.substring(5, 7)) // "核酸"
// 3. startsWith 判断是不是以某个字符开头
// const str = 'pink老师上课中'
// console.log(str.startsWith('pink')) // true
// 4. includes 判断某个字符是不是包含在一个字符串里面
const str = '我是pink老师'
console.log(str.includes('pink')) // true
</script>
小小综合案例(赠品):
需求:
<script>
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('')
</script>
4. Number
toFixed
<script>
// toFixed 方法可以让数字指定保留的小数位数
const num = 10.923
console.log(num.toFixed(1)) // 10.9 四舍五入
const num1 = 10
console.log(num1.toFixed(2)) // 10.00
</script>
三.案例(购物车)
-
需求
-
思路:
就是渲染模块+合计模块
渲染模块灵活应用split,map,join -
代码
<script>
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 => { // 箭头函数只有一个参数省略括号
// 对象解构
const { name, price, picture, count, spec, gift } = item
// 需要处理的数据有 spec, gift, subTotal
// spec 需要取出对象的所有value(数组),再用'/'隔开(字符串),这里用text来接这个结果
const text = Object.values(spec).join('/')
// gift 需要先判断是否有赠品,如果有就把这个字符串搞成数组,再用map方法把每一个数组元素放进span盒子,最后再连接字符串
const str = gift ? gift.split(',').map(item => `<span class="tag">【赠品】${item}</span>`).join('') : ''
// subTotal 小计 单价*数量 保留两位小数
const subTotal = ((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">${subTotal}</p>
</div>
`
}).join('')
// 2. 合计模块
const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0)
// console.log(total)
document.querySelector('.amount').innerHTML = total.toFixed(2)
</script>