简书高级

js高级第一天

箭头函数

箭头函数的体验
const func3 = () => {
            console.log(33);
        }
        func3()
箭头函数传参

箭头函数只传入一个函数时,小括号可以省略 const func2 = a => {}

当传入的参数个数不等于1时,小括号都不可以省略 1.const func2 = () => {} 2.const func2 = (a,b) => {}

        const func2 = a => {
            console.log(a);
        }
        func2(2)
箭头函数返回值简写

简写返回值的写法,如果函数只有一行代码,那么大括号可以省略 同时 这一行的代码运行结果也会被直接返回

如果想要省略大括号,就不要换行,理论上可以换,但不美观

const func2 = (a) => a + 1
console.log(func2(2));
箭头函数返回对象

如果箭头函数在省略大括号的情境下,想要返回一个对象,固定语法,添加一个小括号

const func1 = () => ({ uname: '小黑' })
console.log(func1());

参数默认值写法

(msg = '闷') '闷'就是msg的默认值

如果调用函数时,没有传递,就使用默认值

如果传递了参数 就是使用传递的参数,而不会使用,默认值

const func1 = (msg = '闷') => console.log(msg);
// func1('好热')
func1()  //闷

解构

数组解构
const arr = [1, 2, 3, 4]
// 获取 数组的  前两个数据
// 数组解构  关注  顺序
const [str1, str2] = arr
console.log(str1, str2);
变量解构

交换两个变量

let a = 100;

let b = 200;

//交换两个变量

[b, a] = [a, b]

console.log(a, b);// a=200   b=100
对象解构
        let obj = {
            uname: '小马',
            age: 18,
            sex: '男'
        }
        // 相当于let uname = obj.uname   let age = obj.age
        let { uname, age, sex } = obj
        console.log(uname, age, sex);

对象简写

如果变量名称和对象属性名称一致,可以使用对象简写

注意函数简写,省略了:function

        const uname = '小黑'
        const age = 19
        // const obj = {
        //     uname: uname,
        //     age: age
        // }
        // 简写
        // 如果变量名称和属性名称一致,可以写成下列方式
        const obj = {
            uname,   //uname:uname
            age,  //age:age
            say() {
                console.log('你好');
            }
        }
        console.log(obj);
        obj.say()

剩余运算符

是一种比较方便我们获取数据的方式

语法:...

数组中使用:
      const arr = ['a', 'b', 'c', 'd'];
      // 希望可以获取到 剩下所有 元素  都放在新的数组中
      const [let1, let2, ...list] = arr;
      console.log(list);//['c','d']
对象中使用:
      const obj = { a: 1, b: 2, c: 3, d: 4 };
      const { a, b, ...obj2 } = obj;
      console.log(obj2);//[c,d]
传参数中使用:
    // 假设需求 封装一个函数 自动帮我计算 传入数据的 总和 

    // calc(1);// 1 
    // calc(1,2);// 3
    calc(1, 2, 3);// 6
    // calc();


    function calc(...params) {
      // params 可以获取到所有 传递给 calc 的参数 封装到一个数组中
      console.log(params);  //[1, 2, 3]
      // 对数组做什么业务 都可以   计算总和  计算 最大值 最小值
      // 求和
      let sum = 0
      params.forEach(v => sum = sum + v)
      console.log(sum);
    }
值类型和引用类型:

js数据类型 分成了两种 1 值类型 2 引用类型

1 值类型 简单数据类型 字符串、数字、布尔类型、

2 引用类型 对象 、 数组

两者区别 体现 =

值类型 使用 = 复制

引用类型 使用 = 关联在一起

    let a =1 ;
    let b = a;
    // b a 的一份复制 两个值 一样 但是两个数据是完全独立!
    b=10;
    // a 不会发生变化
    console.log(a);
    const obj = { username: '悟空' };
    // 也使用 =
    const newObj = obj; // newObj 看起来和 obj 数据一样   两个数据 本身一起!  修改了其中的任意一个,另外一个也会收到影响
    newObj.username = '八戒';
    console.log(obj); //{username: '八戒'}
复制引用类型-剩余运算符

对象:

    // 复制一份 对象 , 修改新的数据之后 旧的数据 不要收到影响
    const obj = { username: '悟空', height: 100 };

    // const newObj=obj;
    const newObj = { ...obj };
    // const newObj = { username:"悟空",height:100 };

    newObj.username = '八戒';
    console.log(newObj);  //{username: '八戒', height: 100}
    console.log(obj);  //{ username: '悟空', height: 100 }

数组:

    const list = ['a', 'b'];
    // const newList = list; //
    const newList = [...list];
    newList.push('c');
    console.log(newList); //['a', 'b', 'c']
    console.log(list);  //['a', 'b']

数组方法

map

处理后的数组

返回 处理后的数组

map 数组的一个方法 也会遍历 数组 接收一个函数

      const arr = ['a', 'b', 'c'];
      // ['<li>a</li>','<li>b</li>','<li>c</li>']
      const newArr = arr.map((value) => `<li>${value}</li>`);
      console.log(newArr);
filter

过滤

filter 会遍历数组 返回 满足了你条件的(函数内 返回true!! ) 新的数组

      const arr = [1, 3, 5, 7, 9];
      // 返回 大于 3的数据  重新组成数组
      const newArr2 = arr.filter((value) => value > 3); 
      console.log(newArr);//[5, 7, 9]
every

数组是否全符合

every 检测数值元素的每个元素是否都符合条件 全部都符合 返回 true 否则就返回false

every 对于空数组 也会直接返回true

some

只要有一个条件 都返回true

some 检测数组元素中 只要有一个条件 都返回true

find(用于对象数组)

用找满足条件的数组中一个元素

特点:找到了之后 不会再继续往下遍历

find 返回符合 条件的数组元素。

findIndex(用于对象数组)

符合条件的元素的下标

用法可以find很类似 在函数中 如果找到了 返回元素的下标

找不到 就返回 -1

includes(用于简单数组)

判断一个数组是否包含一个指定的值。

有就返回true 没有就返回false

indexOf (用于简单数组)

搜索数组中的元素,并返回它所在的位置

找到了 就返回元素的下标

没有找到了 返回 -1

join

负责把数组 转成 字符串

js高级第二天

Set对象

  1. Set 是一个对象 不会存放重复数据
  2. 数组转成 set对象 const set = new Set([])
  3. set对象 转成 数组 const arr=[...set]
  4. set对象 添加数据 使用add方法
      //  存在旧的数组
      const list = [1, 4, 5, 6, 7];

      //  1 Set对象 需要被 new 出来使用
      const set = new Set(list);

      // 2 存放数据  调用 add方法
      set.add(1);
      set.add(2);
      set.add(2);
      set.add(2);
      set.add(2);
      set.add(2);
      set.add(2);
      set.add(3);

      // console.log(set);
      // 把set对象 转成数组
      const arr = [...set];
      console.log(arr);//[1,2,3,4,5,6,7]

创建对象的多种方式

1. 创建对象的方式 字面量 => 字面意思

不方便维护 - 修改

      const obj = { nickname: '八戒', height: 190 };
      const obj1 = { nickname: '八戒', height: 190 };
      const obj2 = { nickname: '八戒', height: 190 };
      const obj3 = { nickname: '八戒', height: 190 };
      const obj4 = { nickname: '八戒', height: 190 };
      const obj5 = { username: '八戒', height: 190 };
2. 工厂函数 封装

方便维护和修改,但是不能实现继承

      function p(name,a,b,c,d,e) {
        return {
          nickname:name,
          a,b,c,d,e
        }
      }
3. 重点介绍 构造函数

构造函数

构造函数的特点
  1. 构造函数 本质 其实也是一个函数
  2. 作用 用来创建对象
  3. 常用系统自带构造函数(Set 构造函数、Array 构造函数、Object、String、Number、Boolean、Date)
  4. 只要它被new 它 就是构造函数
  5. 首字母是大写(规范)

例:Person 构造函数

per 被new出来的对象 per称为实例!

      function Person() {}

      // Person 就是一个构造函数 被new
      const per = new Person();//per 被new出来的对象   per称为实例!
构造函数中的this

构造函数 默认情况下 就是返回了 this

this 等于你所new出来的实例 per

只要给构造函数中的this 添加 属性或者方法;那么 实例 自然拥有对应的属性和方法

    function Person() {
      this.username = '悟空'; // per也增加了一个属性
      this.add = () => { };
      this.clear = () => { };
    }

    const per = new Person();
    per.username = '八戒';

    const per2 = new Person();

    console.log(per);//{username: '八戒', add: ƒ, clear: ƒ}
    console.log(per2);//{username: '悟空', add: ƒ, clear: ƒ}
构造函数-弊端

构造函数里面的方法会存放在不同的地址中

例:

      function Person() {
        this.say = function () {};
      }
      const p1 = new Person();
      const p2 = new Person();
      console.log(p1 === p2); // 两个对象的比较 内存地址 false
      console.log(p1.say === p2.say);// false 两个函数 存放在不同地址中

      // const s1 = new Set();
      // const s2 = new Set();
      // console.log(s1 === s2);// false
      // console.log(s1.add === s2.add); // true 

      // s1 和 s2 共享一个方法   
      // p1 和 p2 没有共享一个 
对象在堆中的情况

字面量对象:


image.png

工厂函数:

image.png

构造函数:在构造函数中 当我们定义方法的时候 一般都不会只在在 构造函数中写死 ;让我们方法 都指向外部 单独声明的方法 多个实例去共享方法

image.png
构造函数基本使用

构造函数的时候 属性 分成了两种

  1. 函数类型的属性 ;一般都是写在外部(提取函数到构造函数外部,实现了多个实例共享一个函数(优化内存空间;弊端:污染全局变量(使用原型可避免))
  2. 非函数类型的属性;一般是写在内部
      // 构造函数的方式 创建一个对象

      // 姓名 属性
      // 说出自己的姓名 方法

      function say() {
        console.log('这个是Person的一个方法', this.name);
      }
      function fly() {
        console.log(this.name, '要起飞');
      }

      function Person(name, height) {
        this.name = name;
        this.height = height;
        this.say = say;
        this.fly = fly;
      }
      const p1 = new Person('八戒', 150);
      // p1.say();
      p1.fly();
构造函数 + 原型 搭配使用
  1. 原型 本质是一个对象 在我们创建构造函数的时候就拥有

  2. 在原型上添加的一些方法,可以直接被 实例所使用和共享

  3. 可以这么理解 构造函数=父亲 实例=孩子 原型=DNA

  4. 使用面向对象的方式来创建对象

      4.1 构造函数内部 来定义 非函数类型的属性 如 姓名 身高 肤色 性别 
    
      4.2 原型来定义  函数类型的属性 函数 
    

面对对象编程案例:

点击按钮图片放大

    <button> 变大</button>
    <script>

      function MyImg(src) {
        // body标签上能出现一张图片
        const img = document.createElement('img');
        img.style.transition = '2s';
        // 设置 图片地址
        img.src = src;
        // 在body标签上看见这一张图片
        document.body.append(img);

        this.abc = img;
      }

      // 原型上写一写函数
      MyImg.prototype.scale = function (num) {
        // 获取到 构造函数中 创建的  img dom元素 - 提前把img dom  添加到 this的属性中
        this.abc.style.transform = `scale(${num})`;
      };
      const myImg = new MyImg('./images/1.png'); // body标签上能出现一张图片
      const myImg2=new MyImg("./images/1.png");
      const button = document.querySelector('button');


      button.addEventListener('click', function () {
        // myImg.scale(2);// 
        myImg.scale(3); //  3 倍

        myImg2.scale(5);
      });

    </script>

js高级第三天

构造函数+原型

构造函数 是一个函数 作用 创建对象的 用法 必须要new

原型 理解 DNA 在构造函数的原型上所定义的方法 用在实例中

实例 通过构造函数所创建出来的对象

构造函数中 关键字 this === 被new出来的实例

      // 构造函数
      function Person(name) {
        // 实例对象 对象添加属性
        // p1.name=name;

        this.name = name;
      }

      // 方法定义在原型上
      Person.prototype.scale = function () {
        console.log(this.name, '放大');
      };

      // p1 实例 对象
      const p1 = new Person('悟空');

      const p2 = new Person('八戒');

      p1.scale();
      p2.scale();
原型实现方法的继承

儿子的构造函数.prototype.方法名称 = 父亲的构造函数.prototype.方法名称

      function Person(name) {
        this.name = name;
      }

      Person.prototype.say = function () {
        console.log('父亲的say方法');
      };

      function YellowPerson(name, color) {
        Person.call(this, name); // 属性的继承
        this.color = color;
      }

      YellowPerson.prototype.say = Person.prototype.say;
      YellowPerson.prototype.fly = function () {
        console.log('儿子自己的方法 fly');
      };
原型实现属性的继承

父亲的构造函数.call(this,参数。。。)

call的本质:属性的继承 在 儿子的构造函数中 调用 父亲的构造函数

      function Person(name) {
        this.username = name;
      }

      function YellowPerson(name) {
        Person.call(this, name); // 属性的继承
      }

      const yp = new YellowPerson('悟空');
      console.log(yp);
类的基本使用

es6 class面向对象(工作中常用)

      //  es6 新 简洁  class 面向对象

      class Person {
        name = '悟空';
        color = '黄色';
        say() {
          console.log(this.name, this.color);
        }
        fly(){
          console.log(this.name,"起飞");
        }
      }

      // es5 原型链方式实现  面向对象
      // function Person() {
      //   this.name="悟空";
      //   this.color="黄色";
      // }
      // Person.prototype.say=function(){
      //   console.log(this.name,this.color);
      // }

      const p1 = new Person();
      p1.say();
      p1.fly();
如果 属性 可以由外部传入 必须使用构造器
      class Person {
        // 构造器
        constructor(name, color) {
          // 当 Person被new的时候 这个构造器 就会被调用

          console.log('person被new啦');
          // console.log(name,color);

          // this 还是指向 实例
          this.name = name;
          this.color = color;
        }
        say() {
          console.log(this.name, this.color);
        }
      }

      const p1 = new Person('悟空', '黄色');
      console.log(p1);
类的方式来实现继承

extends

如果你写了 extends 而且 还写 constructor

那么在我们的 constructor 必须要调用super 固定语法!!

      class Person {
        constructor(name, color) {
          this.name = name;
          this.color = color;
        }
      }

      class YellowPerson extends Person {
        // 默认的代码
        constructor(name, color, height, weight) {
          super(name, color);// 调用父亲的构造器 给儿子 添加属性 
          this.height = height;
          this.weight = weight;
        }
      }

      const yp = new YellowPerson('悟空', '黄色', 100, 200);
      console.log(yp);
检测数据类型

基本的数据类型 typeof

引用数据类 intanceof——检测 这个实例是不是被某个构造函数

      class Person {}
      class SuperPerson{}
      const p1 = new Person();
      const s1 = new SuperPerson();

      console.log(p1 instanceof Person);//  true
      console.log(p1 instanceof SuperPerson); // false 
this 指向

一般来说 this的指向 判断依据 谁调用了 函数 this 指向谁

1 当我们定义全局的函数的时候 本质是给window添加了一个 属性(函数类型)

2 当我们调用这个函数 的时候 abc() 本质 window.abc() -- window 可以被省略而已

箭头函数没有内部的this

1 箭头函数没有内部的this

2 当你的函数执行体代码中 有出现了 this 慎用 箭头函数!! - 遵循!!

bind 、call 、 apply 修改 this的指向

1 call 和 apply 会在调用原函数的同时也修改this的指向

2 bind会帮你修改this指向 但是 不会直接调用原函数 而是会返回一个 修改了this指向 的新函数

2.1

const fn = obj.say.bind(newObj);
      fn(1, 2);

3 call 和 apply 区别 传递参数的方式不同而已

3.1 obj.say.call(newObj,1,2)

3.2 obj.say.apply(newObj,[1,2]) // 参数必须要以数组的形式来传递

原型继承

用这种方式儿子原型直接指向父亲原型,修改儿子原型,父亲原型也会被修改,所以一般不用

      // 让儿子的原型 指向 父亲的原型
      // YellowPerson.prototype = Person.prototype;

改善:先复制一个父亲原型,再用儿子原型指向复制的父亲原型

      // 对象复制
      YellowPerson.prototype = { ...Person.prototype };
      //
      YellowPerson.prototype.constructor = YellowPerson;
      const yp = new YellowPerson();
      console.log(yp);
      //给儿子一个方法,然后查看父亲的原型,验证修改儿子原型不会影响父亲原型
      // YellowPerson.prototype.aabbcc = function () {};

      // const p1 = new Person();
      // console.log(p1);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容