ECMAScript 6
构造函数
深入对象
1. 创建对象三种方式
- 利用对象字面量创建对象
const o = { name: '佩奇' }
- 利用 new Object 创建对象
const o = new Object({ name: '佩奇' }) console.log(o) // { name: '佩奇' } const obj = new Object() obj.name = '佩奇' console.log(obj) // { name: '佩奇' }
- 利用构造函数创建对象
2. 构造函数
- 概念
一种特殊的函数,主要用来快速 创建多个类似的对象 - 语法
构造函数在技术上是常规函数,但其命名以大写字母开头
只能由new
操作符来执行function Pig(name, age, gender) { this.name = name this.age = age this.gender = gender } const Peppa = new Pig('佩奇', 6, '女') const George = new Pig('乔治', 3, '男') const Mom = new Pig('猪妈妈', 30, '女') const Dad = new Pig('猪爸爸', 32, '男') console.log(Peppa, George, Mom, Dad);
- 说明
- 使用
new
关键字调用函数的行为被称为 实例化 - 实例化构造函数没有参数时,可省略
()
,但不提倡省略 - 构造函数内部无需写
return
,返回值为 新创建的对象
构造函数内部的return
返回的值无效,故不要写return
new Object()
、new Date()
也是实例化构造函数
- 使用
- 实例化执行过程
- 创建一个新的空对象
- 构造函数 this 指向新对象
- 执行构造函数代码,修改 this,添加新属性
- 返回新对象
3. 实例成员 & 静态成员
- 实例成员
实例对象:通过构造函数创建的对象
实例成员:实例对象中 的属性和方法(即 实例属性 和 实例方法 )
说明:
① 为构造函数传入参数,创建结构相同但值不同的对象
② 构造函数创建的实例对象彼此独立,互不影响function Pig(name) { this.name = name } const peiqi = new Pig('佩奇') const qiaozhi = new Pig('乔治') peiqi.name = '小猪佩奇' peiqi.sayHi = () => { console.log('hi~') } console.log(peiqi) console.log(qiaozhi)
- 静态成员
构造函数中 的属性和方法(即 静态属性 和 静态方法)
说明:
① 静态成员只能构造函数来访问
② 静态方法中的 this 指向构造函数
如Date.now()
、Math.PI
、Math.random()
function Pig(name) { this.name = name } Pig.eyes = 2 // 【静态属性】 Pig.sayHi = function () { // 【静态方法】 console.log(this) // Pig(name) { this.name = name } console.log(this.eyes) // 2 【箭头函数无this】 } Pig.sayHi() console.log(Pig.eyes) // 2
内置构造函数
- JS 的主要数据类型
基本数据类型:字符串、数值、布尔、undefined、null
引用类型:对象 - 包装类型
字符串、数值、布尔等基本类型专门的构造函数【JS 中几乎所有的数据都可以基于构造函数创建】const str = 'pink' // 等价于 // const str = new String('pink') // JS底层完成,即把简单数据类型包装为引用数据类型
- 内置构造函数
引用类型:Object、Array、RegExp、Date 等
包装类型:String、Number、Boolean 等
1. Object
- 用于创建普通对象。推荐使用字面量方式声明对象,而非 Object 构造函数
const user = new Object({ name: '小明', age: 15 })
- 三个常用 静态方法
Object.keys(o)
获取对象中所有属性(键),且返回的是一个数组Object.values(o)
获取对象中所有属性(值),且返回的是一个数组Object.assign(newObj, oldObj)
用于对象拷贝,经常给对象添加属性- 示例
const user = { name: '小明', age: 15 } // for (let k in user) { // console.log(k, user[k]) // name 小明, age 15 // } const keyArr = Object.keys(user) console.log(keyArr) // ['name', 'age'] const valueArr = Object.values(user) console.log(valueArr) // ['小明', 15] const copyArr = {} Object.assign(copyArr, user) console.log(copyArr) // {name: '小明', age: 15} Object.assign(copyArr, { gender: '女' }) console.log(copyArr) // {name: '小明', age: 15, gender: '女'}
2. Array
- 用于创建数组。推荐使用字面量创建,而非 Array 构造函数
const arr = new Array(3, 5) console.log(arr) // [3, 5]
- 十四个常用 实例方法
arr.forEach()
遍历 数组,常用于查找遍历数组元素【不返回数组】arr.filter()
过滤 数组【返回新数组,返回的是 筛选满足条件 的数组元素】arr.map()
迭代 数组【返回新数组,返回的是 处理之后 的数组元素】arr.reduce(function(上一次的值, 当前值){}, 初始值)
累计器,常用于求和【返回累计处理的结果】const arr1 = [1, 5, 8] const arr2 = [{ name: '张三', salary: 10000 }, { name: '李四', salary: 10000 }, { name: '王五', salary: 10000 }] const total1 = arr1.reduce(function (prev, current) { return prev + current }) console.log(total1) // 14 const total2 = arr1.reduce((prev, current) => prev + current, 10) console.log(total2) // 24 const total3 = arr2.reduce((prev, current) => prev + current.salary * 1.3, 0) console.log(total3) // 39000 【若数组的第一个值是对象,不能直接加,且必须令初始值为0】
arr.join()
数组元素拼接为字符串【返回字符串】<body> <div></div> <script> // const spec = { size: '40cm*40cm', color: '黑色' } => 40cm*40cm/黑色 // 思路:获取所有属性值,再拼接为一个字符串 // ① 获得所有属性值:Object.values() 返回的是数组 // ② 拼接数组:join('') 转换为字符串 const spec = { size: '40cm*40cm', color: '黑色' } document.querySelector('div').innerHTML = Object.values(spec).join('/') </script> </body>
arr.find(callback(element[, index[, array]])[, thisArg])
① element 当前遍历到的元素 ②index 当前遍历到的索引 ③ array 数组本身
查找元素【返回符合测试条件的第一个数组 元素值,若无,返回 undefined】const arr = [ { name: '小米', price: 1999 }, { name: '华为', price: 3999 }, { name: 'vivo', price: 2999 } ] const res = arr.find(item => item.name === '华为') console.log(res)
arr.every(callback(element[, index[, array]])[, thisArg])
① element 当前遍历到的元素 ②index 当前遍历到的索引 ③ array 数组本身
检测数组所有元素是否都符合指定条件【若是,返回 true;否则,返回 false。若收到一个空数组,无论什么情况都返回 true】const arr = [10, 20, 30] const flag1 = arr.every(item => item >= 10) console.log(flag1) // false
arr.some()
检测数组中的元素是否满足指定条件【若有,返回 true;否则,返回 false】const arr = [10, 20, 30] const flag2 = arr.some(item => item >= 50) console.log(flag2) // false
arr.concat()
合并两个数组【返回新数组】arr.sort()
对原数组单元值排序arr.splice()
删除 / 替换原数组单元arr.reverse()
反转数组arr.findIndex()
查找元素的索引值arr.from()
伪数组转换为真数组<body> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> const oldLis = document.querySelectorAll('ul li') console.log(oldLis) // NodeList(3) // oldLis.pop() // 【报错】伪数组,无该方法 const newLis = Array.from(oldLis) newLis.pop() console.log(newLis) </script> </body>
3. String
- 十二个常见 实例方法
length
用来获取字符串的长度split('分隔符')
用来将字符串拆分成数组const str1 = 'pink,red' console.log(str1.split(',')) // ['pink', 'red'] const str2 = '2022-4-8' console.log(str2.split('-')) // ['2022', '4', '8']
substring(需要截取的第一个字符的索引号[, 结束的索引号])
用于字符串截取【不包含结束的索引号的内容;若省略结束的索引号,默认取到最后】
注:substr()
未来可能会被移除掉,应避免使用const str1 = '今天又要做核酸了' console.log(str1.substring(5, 7)) // 核酸 console.log(str1.substring(5)) // 核酸了
startsWith(检测字符串[, 检测位置索引号])
检测是否以某字符开头【区分大小写】const str1 = '今天又要做核酸了' console.log(str1.startsWith('今天')) // true
includes(搜索的字符串[, 检测位置索引号])
判断一个字符串是否包含在另一个字符串中,返回 true / false【区分大小写】const str1 = '今天又要做核酸了' console.log(str1.includes('核酸')) // true
toUpperCase
用于将字母转换成大写toLowerCase
用于将字母转换成小写indexOf
检测是否包含某字符endsWith
检测是否以某字符结尾replace
用于替换字符串,支持正则匹配match
用于查找字符串,支持正则匹配num.toString()
、String(num)
转换为字符串
- 案例
<body> <div></div> <script> const gift = '50g的茶叶,清洗球' document.querySelector('div').innerHTML = gift.split(',').map(item => `<span>【赠品】${item}</ span> <br>`).join('') </script> </body>
4. Number
- 一个常用方法
toFixed()
设置保留小数位的长度【四舍五入】const num1 = 10.923 console.log(num1.toFixed(1)) // 10.9 console.log(num1.toFixed(0)) // 11 const num2 = 10 console.log(num2.toFixed(2)) // 10.00
综合案例
购物车案例
- js 中,应尽量避免小数运算,小数转换为整数
0.1 + 0.2 === 0.3 // false
(0.1 * 100 + 0.2 * 100) / 100 === 0.3 // true
document.querySelector('.list').innerHTML = goodsList.map(item => { const { picture, name, count, price, spec, gift } = item const text = Object.values(spec).join('/') // const subTotal = (price * count).toFixed(2) const subTotal = ((price * count * 100) / 100).toFixed(2) const str = gift ? gift.split(',').map(item => `<span class="tag">【赠品】${item}</span>`).join('') : "无" return ` <div class="item"> <img src=${picture} alt=""> <p class="name">${name} ${str}</p> <p class="spec">${text}</p> <p class="pirce">${price.toFixed(2)}</p> <p class="count">${count}</p> <p class="sub-total">${subTotal}</p> </div> ` }).join('') const total = goodsList.reduce((prev, item) => prev + (item.price * item.count * 100) / 100, 0) document.querySelector('.amount').innerHTML = total.toFixed(2)