JS高级的学习(二)

set对象
  1. Set 是一个对象 存放数据 数据永远不会重复
  2. Set 当成是一个数组 遍历 使用 数组方法 find findIndex Map
    1. 数组转成 Set对象 const set = new Set([])
    2. Set对象转成 数组 const arr=[…set]
        //  旧的数组const list = [1, 2, 3, 4, 5]// 1.Set对象 需要被 new 出来使用// const set = new Set()const set = new Set(list)// 2.存放数据  调用 add方法set.add(7)set.add(8)set.add(8)set.add(9)console.log(set)// 3.把set对象 转成数组const arr = [...set]console.log(arr)
创建对象的n种方式
  1. 字面量 不方便维护,修改
  2. 工厂函数 封装 继承,参数一多也很麻烦
  3. 重点介绍 构造函数
        // 创建对象的方式:// 字面量 不方便维护 - 修改// const obj = { nickname: '悟空', height: 190 }// const obj1 = { nickname: '八戒', height: 100 }// const obj2 = { nickname: '沙和尚', height: 80 }// 工厂函数  封装 继承,参数一多也很麻烦function person(name, height, a, b, c, d, e) {return {nickname: name,height,a,b,c,d,e,}}const obj = person('悟空', 190)const obj1 = person('八戒', 100)const obj2 = person('沙和尚', 80)console.log(obj)console.log(obj1)console.log(obj2)// 最重要的是 构造函数
箭头函数 没有this指向
  1. 箭头函数没有内部的this
  2. 当函数执行体代码中 有出现了 this 慎用 箭头函数
        const obj = {username: "悟空",say: () => console.log(this) // this指向window}const funct1 = () => console.log(this) // this指向windowobj.say()funct1()const button = document.querySelector("button")button.addEventListener("click", function () {this.innerText = "被修改了哈哈"console.log(this) // 按钮本身})button.addEventListener("click", () => {// this.innerText = "被修改哈" // error,this指向window了console.log(this) // window})
全局函数的this的指向
  1. 一般来说 this的指向 判断依据 谁调用了 函数 this 指向谁
  2. 其实 当定义了全局的函数的时候,默认是挂载到了window 全局变量上
  3. 全局函数 其实就是 window的一个属性而已 只不过 平时写代码的时候 可以省略这个window
    1. 当定义全局的函数的时候 本质是给window添加了一个 属性(函数类型)
    2. 当调用这个函数的时候 如:person() 本质 window.person() window 可以被省略而已
        function person() {console.log("ABC")console.log(this) // this指向window}person() // 调用了this,this指向了windowwindow.sonPerson = function () {console.log('ABC')console.log(this) // this指向window}window.sonPerson() // 调用了this,this指向了windowconst obj = {username: "悟空",say() {console.log(this) // this指向obj}}obj.say()
构造函数
  1. 构造函数 本质 其实也是一个函数

  2. 作用 用来创建对象

  3. 以前见过构造函数

  4. 只要它被new 它就是构造函数

    1. 如:Person 构造函数 首字母是大写(规范)
    2. 如:per 被new出来的对象是 实例
        // Person 就是一个构造函数 被newfunction Person() {}// per 就是实例const per = new Person()
构造函数的this
  1. 每一个构造函数中 都存在 一个 魔鬼 this
  2. 构造函数 默认情况下 就是返回了 this
  3. this 等于你所new出来的实例
        // 只要给构造函数中的this 添加 属性或者方法// 那么 实例 自然拥有对应的属性和方法function Person() {this.username = '悟空' // Person增加了一个属性this.add = function () {} // Person增加了一个方法this.clear = function () {}}// 注意:console.log(Person.username) // 无法拿到Person的元素console.log(Person.username = '沙和尚') // 控制台显示 沙和尚,但实际Person里面的username还是 悟空console.log(Person) // username属性还是 悟空console.log(this.username) // 无法拿到Person的元素const per = new Person()per.nickname = '八戒' // 直接添加,per有、per2没有const per2 = new Person()console.log(per)console.log(per2)console.log(per2.username) // 可以拿到Person的元素
构造函数的弊端
        function Person() {this.say = function () {}}// p1 和 p2 没有共享一个方法(占更多的内存)const p1 = new Person()const p2 = new Person()console.log(p1 === p2) // false 两个对象的比较 内存地址 console.log(p1.say === p2.say) // false 两个函数 存放在不同地址中// s1 和 s2 共享一个方法const s1 = new Set()const s2 = new Set()console.log(s1 === s2) // false 两个对象的比较 内存地址 console.log(s1.say === s2.say) // true 两个函数 存放在相同地址中
构造函数-方法指向同一个(这个全局(方法)变量不推荐,后面的 构造函数+原型 更好 )
  1. 值类型 是存在 栈空间 适合存放 固定大小的数据
  2. 引用类型(对象、数组、函数) 存在 堆空间 适合存放大小不固定的数据
  3. new了两个对象的时候, 两个对象的内存地址 不相等
  4. 希望 两个对象的方法 内存地址是相等
    1. 在构造函数中 当我们定义方法的时候 一般都不会只在 构造函数中写死
    2. 让 方法 都指向外部 单独声明的方法 多个实例去共享方法
  5. 缺点:污染全局变量,意思是有其他人可能使用这些属性、方法,就会造成覆盖
        // newSay 全局(方法)变量function newSay() {console.log('外部单独的newSay方法')}function Person() {this.say = newSay}const p1 = new Person()const p2 = new Person()console.log(p1 === p2) // false console.log(p1.say === p2.say) // true
构造函数基本使用(这个全局(方法)变量不推荐,后面的 构造函数+原型 更好 )
  1. 构造函数的属性

    1. 函数类型的属性(指方法):一般都是写在外部
    2. 非函数类型的属性(指属性):一般是写在内部
        // say 全局(方法)变量function say() {console.log('这个是Person的一个方法', this.name)}// fly 全局(方法)变量function fly() {console.log(this.name, '要起飞')}function Person(name, height) {this.name = namethis.height = heightthis.say = saythis.fly = fly}const p1 = new Person('八戒', 150)p1.say()p1.fly()console.log(p1)console.log(p1.name, p1.height)
构造函数+原型(es6比es5(构造函数+原型)更好)
  1. 原型 本质 是一个对象
  2. 当创建一个构造函数的时候 原型 就被创建了
  3. 如果我们在原型对象上 增加一个属性或者方法 那么 实例 拥有所增加的属性或者方法
  4. 原型 就是 DNA;构造函数 就是 父亲;实例 就是 孩子
        function Person() {this.name = '悟空'this.b = function () {}}console.log(Person.prototype)// 访问原型Person.prototype.a = function () {console.log('这个是a方法')}const p1 = new Person()console.log(p1)p1.a()
原型实现方法的继承-prototype
        function Person() {}Person.prototype.say = function () {console.log('father', '父亲定义的say方法')}const father = new Person()function SonPerson() {}//  让孩子SonPerson去复用父亲Person的方法  即继承父亲的方法SonPerson.prototype.say = Person.prototype.say// 添加其他方法SonPerson.prototype.jump = function () {console.log('son', '孩子自己的方法')}const son = new SonPerson()Person.prototype.say() // ok:Person的原型(prototype)的方法say()SonPerson.prototype.say() // ok:SonPerson的原型(prototype)的方法say()// son.say = father.say // 等同于 SonPerson.prototype.say = Person.prototype.say  前提条件:Person和SonPerson都被 new 后son.say()son.jump()
原型实现属性的继承-call
        function Person(name, color, height, weight) {this.name = namethis.color = colorthis.height = heightthis.weight = weight}function SonPerson(name, color, height, weight, nickname, gender) {// Person父亲中也有  注意:this不能忘写Person.call(this, name, color, height, weight) // 属性的继承 // SonPerson孩子this.nickname = nicknamethis.gender = gender}const son = new SonPerson('悟空', '黄色', 150, 250, '弼马温', '公')console.log(son)console.log(son.name)
原型快速继承
         // 作用:快速将父亲的原型复制到儿子上function Person() {}Person.prototype.add = function () {}Person.prototype.remove = function () {}Person.prototype.clear = function () {}function SonPerson() {}// SonPerson.prototype.add= Person.prototype.add// SonPerson.prototype.remove= Person.prototype.remove// SonPerson.prototype.clear= Person.prototype.clear// 让儿子的原型 指向 父亲的原型// SonPerson.prototype = Person.prototype // error:堆地址联系在一起,修改一个,另一个也被修改// 对象复制(剩余运算符)SonPerson.prototype = {...Person.prototype}SonPerson.prototype.cunstructor = SonPerson // 添加方法到SonPerson的原型SonPerson.prototype.del = function () {} // 添加方法到SonPerson的原型const son = new SonPerson()console.log(son)const per = new Person()console.log(per)
es6类的基本使用
  1. 构造函数 来创建对象
  2. 对象 两种属性信息
    1. 非函数类型的属性(指属性)
    2. 函数类型的属性(指方法)
        // es6 新 简洁  class 面向对象class Person {// this不用写,一写就报错name = '悟空'color = '红色'say() {console.log(this.name, this.color)}fly() {console.log(this.name, '起飞')}}// es5 原型链方式实现  面向对象function Person2() {this.name = "悟空"this.color = "紫色"}Person2.prototype.say = function () {console.log(this.name, this.color)}Person2.prototype.fly = function () {console.log(this.name, '降落')}const p1 = new Person()p1.say() // 悟空 红色p1.fly() // 悟空 起飞const p2 = new Person2()p2.say() // 悟空 紫色p2.fly() // 悟空 降落
es6类的(动态)基本使用
        //   使用 class 来定义属性的时候//     1.如果 这个属性 写死了//       class Person {//         name="悟空"//         color="黄色"//       }//     2.如果 属性 可以由外部传入 必须使用构造器//       constructor(name,color){//         this.name=name//         this.color=color//       }class Person {// 构造器constructor(name, color) {// 当 Person被new的时候 这个构造器 就会被调用console.log('Person被new了')console.log(name, color)// this 还是指向 实例  注意:this要写this.name = namethis.color = color}say() {console.log(this.name, this.color)}}const p1 = new Person('悟空', '红色')p1.say()console.log(p1)
es6类实现属性和方法的继承
        // // es5类 去实现继承// function Person() {//     this.name = "父亲"// }// Person.prototype.say = function () {//     console.log(this.name, "父亲的say方法")// }// function SonPerson(name) {//     Person.call(this, name) // 属性的继承// }// SonPerson.prototype.say = Person.prototype.say // 方法的继承// const son = new SonPerson// console.log(son.name)// son.say()// es6类 去实现继承class Person {name = '父亲'say() {console.log(this.name, '父亲的say方法')}}// 直接实现了 继承父亲的属性和方法class SonPerson extends Person {}// 孩子实例 拥有 父亲 name属性和say方法const son = new SonPerson()console.log(son)console.log(son.name)son.say()
es6类实现(动态)属性和方法的继承
        //   对于孩子来说 //   1.如果写了  extends 而且 还写 constructor //     那么在 constructor 必须要调用super 固定语法//   2.之前只写  extends 不用写super 因为没有写 constructorclass Person {constructor(name, color) {this.name = namethis.color = color}say() {console.log(this.name, this.color)}}class SonPerson extends Person {// 默认的代码constructor(name, color, height, weight) {super(name, color) // 调用父亲的构造器 给孩子 添加属性this.height = heightthis.weight = weight}}const son = new SonPerson('悟空', '紫色', 100, 200)console.log(son)console.log(son.height)son.say()
检测数据类型(检测实例被这个构造函数 new)
        //  检测 基本的数据类型 typeof//  检测 引用数据类类型 intanceof//  检测 这个实例是不是被某个构造函数 new 出来 console.log(typeof '') // stringconsole.log(typeof 1) // numberfunction Person() {}class SuperPerson {}const p1 = new Person()const s1 = new SuperPerson()console.log(p1 instanceof Person) //  trueconsole.log(s1 instanceof SuperPerson) // trueconsole.log(p1 instanceof SuperPerson) // false
对象中的this和call
  1. this 范围很广 主要在 对象中来学习
  2. this 指向 对象本身 可以通过 call 方法来修改
  3. call 在调用方法的时候,可以修改 this 的指向
  4. call 在调用方法的时候,可以传递参数
        const obj = {height: 100,username: '悟空',say(a) {console.log(this, a) // this指向 obj},}const newObj = {username: '八戒'}obj.say()console.log(obj)obj.say.call() // call修改this的指向,变成windowconsole.log('----------------------------------')obj.say(123)obj.say.call(this, 123) // this指向 windowobj.say.call(newObj, 123) // this指向 newObj
对象添加属性的方式
        // 对象添加属性的普通方式const newObj = {a: 1,b: 1,}newObj.c = 2console.log(newObj)// 在对象中  this = 对象本身    this =  我自己// 当成普通的对象const obj = {a: 1,e: 1,add() {// 给对象添加属性  封装到一个普通的函数中obj.a = 3 // 会覆盖原来的a属性obj.b = 3// 等同上面  obj修改成thisthis.c = 4this.d = 4}}console.log(obj) // add方法没使用时,只有a、e、add()obj.add() // 让方法帮我们添加属性console.log(obj)
动态给对象添加属性-call
        // 当成普通的函数function person(name, color, height, weight) {this.name = namethis.color = colorthis.height = heightthis.weight = weight}// 定义一个空的对象const obj = {}person.call(obj, '悟空', '红色', 150, 250) // obj 借用了person方法 来给自己的属性赋值// 1.调用了 Person 方法// 2.方法内部 给 this赋值   this 等于 obj// 3 this.name=悟空 =>  obj.name = 悟空  //  赋值动作 // 3 this.color=黄色 =>  obj.color = 黄色  //  赋值动作 // 3 this.height=150 =>  obj.height = 150  //  赋值动作 // 3 this.weight=250 =>  obj.weight = 250  //  赋值动作console.log(obj) // 拥有了 Person 函数中一些属性
修改this指向:bind、call、apply
  1. call 和 apply 会在调用原函数的同时也修改this的指向
  2. bind会修改this指向 但是 不会直接调用原函数 而是会返回一个 修改了this指向 的新函数
  3. call 和 apply 区别 传递参数的方式不同而已
    1. 如:obj.say.call(newObj,1,2) // 数字,字符串
    2. 如:obj.say.apply(newObj,[1,2]) // 数组
  4. 默认情况下 this的指向 谁调用了this,this 指向谁
       const obj = {username: '悟空',say() {console.log(this.username, 'obj中的say方法 ')},say1(a, b) {console.log(a, b)},}const newObj = {username: '八戒',}obj.say.call(newObj)obj.say.apply(newObj)const fn = obj.say.bind(newObj) //  返回一个新的函数  新函数内部 修改this指向的功能fn()console.log('---------------------------')obj.say1.call(newObj, 1, 2)obj.say1.apply(newObj, [1, 2]) // 参数必须要以数组的形式来传递const fn1 = obj.say.bind(newObj)fn1(1, 2)

JS高级的学习(二)相关推荐

  1. JS高级——模块化学习笔记

    一.什么是模块化? 到底什么是模块化.模块化开发呢? 事实上模块化开发最终的目的是将程序划分成一个个小的结构: 这个结构中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他的结构: 这个结构可以将 ...

  2. JavaScript高级程序设计学习(二)之基本概念

    任何语言的核心都必然会描述这门语言基本的工作原理.而描述的内容通常都要涉及这门语 言的语法.操作符.数据类型.内置功能等用于构建复杂解决方案的基本概念.如前所述, ECMA-262通过叫做 ECMAS ...

  3. js高级程序设计学习

    1 script标签 1.1 script标签属性 src:指定加载的外部js文件 type:在浏览器中为"text/javascript",如果加载或包含ES模块代码,值为mod ...

  4. c++面向对象高级编程 学习二 带指针的类

    带指针的类,必须要自己写拷贝构造和赋值构造 拷贝构造:参数和类的类型一样的构造函数 赋值构造:重写操作符=,且其参数和类的类型一样 class String {public: String(const ...

  5. Node.js高级编程【一】node 基础

    目录 一.Node 基础 1.课程概述 2.Node.js 架构 3.为什么是Node.js ? 4.Node.js 的 异步IO 5.Node.js 主线程是单线程 6.Node.js 应用场景 7 ...

  6. Js高级程序设计第三版学习(十二章)

                                  Js高级程序设计第三版学习(十二章) 第十二章 DOM2和DOM3   1.样式: 访问样式属性 任何支持style特性的HTML元素都有一 ...

  7. day04【JS高级】BOM对象、Window对象、二种定时器、 Location对象、DOM对象、DOM获取元素、DOM操作内容、DOM操作属性、DOM操作样式、DOM操作元素(标签)、 正则表达式

    回顾 1. js基础语法运算符:算数运算符可以与字符串进行数学运算,js底层进行隐式转换比较运算符:===(恒等) 特点,比较类型+内容流程控制语句if判断条件表达式:1)布尔2)数值:非0为真3)字 ...

  8. Js 高级学习教程

    一.Js 高级学习教程 1.Js BOM.DOM 基础概念 2.Js BOM 6大对象 3.Js 定时器使用 4.Js 本地存储 5.Js Dom 操作基本逻辑 6.Js Dom 事件注册 7.Js ...

  9. Python学习 Day26 JS循环语句(二)

    JS循环语句(二) (一)寻找质数 输出1-100之间的质数 for(var num = 1;num <= 100;num++){//累加器,只要遇到是数字num的约数,这个变量就进行+1var ...

最新文章

  1. 2019年终总结--满城灯火,只若初见
  2. Flume监听文件夹中的文件变化,并把文件下沉到hdfs
  3. python open文件安全隐患_python的其他安全隐患
  4. STL模板整理 set
  5. 这些Intel Atom处理器千万别升Windows 10创意者更新:不兼容
  6. 西北师范大学知行学院计算机科学与技术,西北师范大学知行学院电子信息工程专业...
  7. HBase数据模型解析和基本的表设计分析
  8. File类之常用方法
  9. React后台管理系统-订单管理
  10. Jasper报表导出pdf中文不显示——Font simsun is not available to the JVM. See the Javadoc for more det,已解决
  11. c语言智能车跑道检测程序,智能小车的循迹方法与流程
  12. SQL Server中查询累计和与滑动平均值
  13. 用友NC系统与一卡通集成解决方案
  14. Windows中使用Termius
  15. android 读build.prop,Android build.prop简介
  16. 外卖店优先级 第十届蓝桥杯真题 C++
  17. 使用 Ceph 作为 OpenStack 的统一存储解决方案
  18. 氧分呗:新时代定义科技的美好 自主创新踏上新征程
  19. 一杯清茶的时间G-TEA泉舟精英
  20. 2019,先定个小目标

热门文章

  1. WebRTC 教程四: WebRTC聊天室设计和搭建
  2. 关于AntMotion动画使用
  3. c语言visit函数作用,Visit
  4. Ascent代码分析4-World之地图管理及实现结构
  5. 用PHP访问JasperReport
  6. 港科夜闻|香港科大(广州)(筹)与民心港人子弟学校签署合作框架协议
  7. 电子发票多页合并打印在一张纸上
  8. RNA 27 SCI文章中转录因子结合motif富集到调控网络 (RcisTarget)
  9. 自动取款机如何使用无卡取款_无卡取款怎么操作
  10. 易地推招生拓客分享:如何让社群招生成为培训机构招生利器?