day26
一、Symbol
+ 基本数据类型 + 对象的键都是字符串类型的,无论给对象添加什么数据类型作为键,最终都会调用toString()方法转成字符串类型 + 问题 => 字符串类型如果有相同的名称,那么后面的会把前面的给覆盖掉 + 针对于以上的问题,有人提出要是有一种数据,它的结构是独一无二的就好了,所谓的独一无二就是名称即使一样也不会覆盖 + Symbol()类型就符合独一无二的规则 => 参数表示的是描述信息,其实就是值
二、Set
// Set() 数据结构,其实是伪数组,它里面的数据都是唯一的,不能有重复的,如果有重复的会自动过滤 let s = new Set(['a', 'a', 'a', 'b', 'b', 'c', 'c']) console.log(s)
1.数组去重
let arr = ['a', 'a', 'a', 'b', 'b', 'c', 'c'] let s = new Set(arr) console.log(Array.from(s))
2.add(value):添加一个值,返回Set结构本身
3.delete(value):删除某个值,返回布尔值
4.has(value):返回布尔值,表示是否是成员
5.clear():清除所有成员,无返回值
三、Map对象
对象本身添加的键都是字符串类型,如果想要把其他的数据类型当成对象的键最终都会转成字符串类型,Map这种数据结构可以让任意数据类型都变成的对象键
// let a = {name: '张'} // let obj = {} // obj[a] = '哈哈' // console.log(obj) // BigInt 可以表示任意大的整数 // const num = BigInt() let a = {name: '张'} let b = ['a', 'b', 'c'] let mp = new Map([ [123, '我是数字类型'], [a, '我是一个对象'], [b, '我是一个数组'] ]) // console.log(mp.size) // `keys()` : 取出Map里面所有的键 // console.log(mp.keys()) // `values()` : 取出Map里面所有的值 // console.log(mp.values()) // `entries()` :取出里面所有的键和值 // console.log(mp.entries()) // `set()` : 增加、修改 mp.set('hello', '哈哈') // `get()`: 获取 // console.log(mp.get(a)) // console.log(mp.get(b)) // console.log(mp.get('hello')) // `has()`: 判断里面有没有这个值 true / false // console.log(mp.has('hello')) // `delete()` : 删除 mp.delete('hello') // `clear()` : 清除 mp.clear() console.log(mp)
四、面向对象
+ 是一种编程思想 + 编程思想 => 面向过程编程 => 面向对象编程 => 函数式编程 --- 高阶函数、纯函数 + 例如 => 吃饭这件事儿 + 第一种使用面向过程编程思想来解决吃饭的问题 => 菜市场 --- 选菜 --- 买菜 => 备菜 --- 择菜 --- 洗菜 --- 切菜 => 炒菜 --- 掌握火候 --- 调味 => 装盘 => 吃饭 => 洗碗 => ... + 第二种使用面对象程编程思想来解决吃饭的问题 => 点外卖 => 下馆子 + 面向过程编程所以步骤都需要自己参与 + 面向对象不怎么关注过程,怎么解决问题方便怎么来,解决某个问题直接找对应的对象即可,讲究的是怎么把问题解决了就好 + 面向对象也可以理解为资源整合,分工协作 + 面向对象特点 => 封装 => 继承 => 多态
// 创建一个对象 // 对于new Object()或者{}其实就是一个类或者理解为模板,根据这个类创建出了对象 let obj1 = new Object() let obj2 = {}
五、创建对象
1.工厂函数创建对象
let obj1 = { name: '张', age: 18, sex: '男', running(){ console.log(this.name + '喜欢晚上去公园里面跑步!') } } let obj2 = { name: '王', age: 18, sex: '男', running(){ console.log(this.name + '喜欢晚上去公园里面跑步!') } } */ // 问题:大家发现创建出来的多个对象,里面的属性和方法是一样的,只是值不一样,但是写了很多的冗余代码,非常不方便后期的代码的维护,也大大降低了代码的阅读性 // 工厂方式创建对象:工厂的作用大批量的生产商品,效率非常高。工厂方式利于了函数可以传递参数和重复调用的特性 // function person(name, age, sex){ // let obj = new Object() // obj.name = name // obj.age = age // obj.sex = sex // obj.running = function(){ // console.log(this.name + '喜欢晚上去公园里面跑步!') // } // return obj // } function person(name, age, sex){ let obj = { // 注意点:如果对象的键和值是一样的情况下,可以只写键就可以 name, age, sex, running(){ console.log(this.name + '喜欢晚上去公园里面跑步!') } } return obj } let obj1 = person('张', 18, '男') let obj2 = person('王', 20, '男') console.log(obj1, obj2) obj1.running() obj2.running()
2.构造函数创建对象
构造函数内部执行过程,这个过程你看不到,给大家进行模拟下 步骤 + 当使用new关键字来调用函数时,会做以下的操作 + 第一步 => 先进入到构造函数内部 + 第二步 => 会在函数内部创建一个对象 例如:let obj = new Object() || let obj = {} + 第三步 => 会把创建的这个对象赋值给this 例如:this = obj + 第四步 => 进行各种逻辑操作 属性添加和方法添加 + 第五步 => 会把this返回给外界,就是创建的obj返回给外界
// 构造函数条件:函数名称要求首字母大写,其实不大写也可以,主要是为了和其他的函数做区分。调用函数必须前面使用new关键字 // 构造函数就是一个类(class),理解为一个模板,根据这个模板创建出不同的对象 // 专业术语:构造函数、实例化对象、实例属性、实例方法 // 构造函数 function Person(name, age){ // 实例属性 this.name = name this.age = age // 实例方法 this.running = function(){ console.log(this.name + '喜欢晚上去公园里面跑步!') } } // 实例化对象 // 规则:当使用new关键字来调用函数的时候,函数里面的this指向的是这个构造函数的实例化对象 let obj1 = new Person('张', 18) let obj2 = new Person('王', 20) console.log(obj1, obj2)
六、prototype
prototype属性:
+ 每一个构造函数都有一个prototype属性,这个属性指向一个对象(空间) + 存储在这个对象里面的属性和方法,可以被这个构造函数的所有的实例化对象所共享 + 把这个prototype指向的这个对象称之为原型对象
// 构造函数 function Person(name, age){ // 实例属性 this.name = name this.age = age // 实例方法 // this.running = function(){ // console.log(this.name + '喜欢晚上去公园里面跑步!') // } }
// 原型对象 Person.prototype.running = function(){ console.log(this.name + '喜欢晚上去公园里面跑步!') } // 实例化对象 let obj1 = new Person('张', 18) let obj2 = new Person('王', 20) console.log(obj1, obj2) console.log(obj1.running == obj2.running) // true console.log(Array.prototype)
七、构造函数三角关系
prototype属性 + 每一个构造函数都有一个prototype属性,这个属性指向一个对象(空间) + 存储在这个对象里面的属性和方法,可以被这个构造函数的所有的实例化对象所共享 + 把这个prototype指向的这个对象称之为原型对象 constructor属性 + 构造器,其实就是构造函数的内部的空间 + 每一个原型对象都有一个constructor属性,这个属性指向的是这个原型对象的构造函数 __proto__属性 + 隐式原型 + 每一个实例化对象都有一个__proto__属性,这个属性指向是创建这个实例化对象的构造函数的原型对象
八、ES6 class类
ES6 class + class类 + 提供了一个类专门用来创建对象 + class其实是一种语法糖的写法 + 语法糖 => 也译为糖衣语法,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用 => 语言本身不具备这个语法的能力,但是为了方便使用,模拟了一个这种语法 => class这种语法糖的本质上还是构造函数
class Person { constructor(name, age){ this.name = name this.age = age } // 写在这里的方法其实就是放在prototype原型对象里面的了 running(){ console.log(this.name + '喜欢去钓鱼了!') } } let obj1 = new Person('张', 18) obj1.running() console.log(Person.prototype) console.log(Person.prototype.constructor) console.log(obj1.__proto__)