JavaScript高级

147 阅读6分钟

一、箭头函数

<script>
        //定义一个箭头函数,没有形参,没有返回值,2行执行实际业务
        const func1 = () => {
            console.log('执行业务1');
            console.log('执行业务2');
        }

        //没有形参,没有返回值,业务只有一行代码,大括号都可以省略‘
        const func2 = () => console.log('执行业务3');

        //只有一个形参,没有返回值,业务只有一行代码
        // const func3 = a => console.log(a + 1);
        const func3 = (a) => console.log(a + 1);

        //两个或多个参数(括号不能省略),没有返回值,业务只有一行代码
        const func4 = (a, b) => console.log(a + b);

        //没有形参,有返回值,业务两行代码
        const func5 = () => {
            let c = 5;
            return c + 10;
        }

        //没有形参,有返回值,业务一行代码
        const func6 = () => {
            return 100 + 200
        }

        //没有形参,有返回值,业务一行代码,等价上述写法
        const func7 = () => 100 + 200
    </script>

二、常用数组方法

方法描述
every()检测数值元素的每个元素是否都符合条件。
filter() //过滤或者筛选检测数值元素,并返回符合条件所有元素的数组。
find()返回符合传入测试(函数)条件的数组元素。
findIndex()返回符合传入测试(函数)条件的数组元素索引。
forEach() //遍历数组数组每个元素都执行一次回调函数。
includes()判断一个数组是否包含一个指定的值。
indexOf()搜索数组中的元素,并返回它所在的位置。
isArray()判断对象是否为数组。
join()把数组的所有元素放入一个字符串。
map() //根据就数组 重新改造成新数组通过指定函数处理数组的每个元素,并返回处理后的数组。
reduce()将数组元素计算为一个值(从左到右)。
reverse()反转数组的元素顺序。
some()检测数组元素中是否有元素符合指定条件。
sort()对数组的元素进行排序。

三、面向对象

一种编程行业通用的写项目级的代码的思维,引导我们如何编写高质量的代码,万物皆对象 - 看待事物的角度,(属性:数据,行为:动作(方法))。代码特点是封装和继承

1、对象在内存中的示意图

image_xU8W-nS4OY.png

四、创建对象的几种方式

1、字面量

1)简单粗暴

2)不适合创建多个同样类型的对象的场景

const obj ={ name:"悟空",height:100,age:5000};

2、工厂函数

1)容易理解

2)失去血缘关系,无法简单分辨对象的特征

3)后期无法实现继承

image_tiJEudI_9A.png

<script>
    function createPerson(name, age, hight) {
        return {
            // name: name,
            userName: name,
            age: age,
            hight: hight
        }
    }
    const obj1 = createPerson('张三', 18, 180)
    const obj2 = createPerson('李四', 19, 175)
    const obj3 = createPerson('王五', 20, 170)
    console.log(obj1);
    console.log(obj2);
    console.log(obj3);
</script>

3、构造函数

1)工作原理:

构造函数的工作原理: (1)开辟内存空间 (在内存中创建一个新的空对象) (2)让this指向这个新的对象 (3) 执行构造函数里面的代码,给这个心得的对象添加属性和方法 (4)返回这个新对象(所以构造函数里面不需要return)

2)优点

①可以方便的创建对象

②拥有血缘关系

③还有后续更多的优势

    // 1 声明函数 
    function createStudent(name, age) {
      // 2 通过 this 赋值
      this.name = name;
      this.age = age;
    }

    // 3 通过 new 来创建对象
    const obj = new createStudent("悟能", 83);

    console.log(obj);

3)缺点

①同一个say 方法占据了两份内存

    function createStudent(name, age) {
      this.name = name;
      this.age = age;
      this.say = function () {
        console.log(this.name);
      }
    }

    const obj = new createStudent("悟能", 83);
    const obj1 = new createStudent("悟能1", 84);

    console.log(obj.say === obj1.say); // false  不是同一say方法 浪费了内存

image_w4zl4vBQIb.png

4)提取同一个say方法

①解决了浪费内存的弊端

②但是造成了污染全局变量的问题

    // 提前将say 声明好
    function say() {  // 污染全局变量
      console.log(this.name);
    }
    function createStudent(name, age) {
      this.name = name;
      this.age = age;
      this.say = say
    }

    const obj = new createStudent("悟能", 83);
    const obj1 = new createStudent("悟能1", 84);

    console.log(obj.say === obj1.say); // true

image_2wfJyyFJks.png

5)原型模式:在构造函数的原型上存放函数

①解决了同意和say浪费内存的问题

②解决了污染全局变量的问题

    function createStudent(name, age) {
      this.name = name;
      this.age = age;
    }
    // 将刚才的全局函数say 直接挂载到 构造函数的原型上 即可
    // prototype 是个对象 每一个构造函数都会内置有的. 我们称之为原型
    createStudent.prototype.say = function () {
      console.log(this.name);
    }

    const obj = new createStudent("悟能", 83);
    const obj1 = new createStudent("悟能1", 84);

    console.log(obj.say === obj1.say); // true

4、构造函数原型 — prototype

1)每一个构造函数都有一个prototype属性,指向另一个对象

2)prototype也是一个对象,这个对象的所有属性和方法,都会被够着函数所拥有

3)原型的作用:共享方法

5、对象原型 __protp__

1)对象都会有一个属性__protp__ 指向构造函数的prototype原型对象

2)__protp__对象原型和原型对象prototype是等价的

五、ES6

1、变量的简写

1)变量声明

let x; 
let y = 20; 
// 简写
let x, y = 20;

2)多个变量赋值

let a, b, c; 
a = 5; 
b = 8; 
c = 12;
 
// 简写
let [a, b, c] = [5, 8, 12];
 console.log(a, b, c);// 5,8,12

3)三元运算符

if(a = true){
 console.log(1);
}else{
 console.log(2);
}
// 简写
a = true ?  console.log(1) :  console.log(2);

4)交换两个变量

let x = '10', y = "20"; 
const temp = x; 
x = y; 
y = temp; 
// 简写
[x, y] = [y, x];

5)箭头函数

function add(num1, num2) { 
   return num1 + num2; 
} 
// 简写
const add = (num1, num2) => num1 + num2;

6)获取对象中的属性

  const obj = {
    name: "悟空",
    skill: "72变",
    say() { }
  }
  const { name, skill,say } = obj;
  console.log(name, skill,say);// 悟空 72变 function(){}

7)优雅的获取数组最大值和最小值

var arr = [1, 2, 3, 4, 999, 1999];
console.log(Math.max(...arr)); // 1999
console.log(Math.min(...arr)); // 1

2、函数参数的默认值

定义函数的同时,可以给形参一个默认值

    // 定义函数的同时,可以给形参一个默认值
    function show(msg = '你好', str = '大家好') {
        console.log(msg, str);
    };
    show() //你好  大家好
    show('哈喽')  //哈喽   大家好
    show('大家好啊', '才是真的好')   //大家好啊   才是真的好

3、...拓展运算符||剩余运算符

1)剩余

const [a,...b] = [1,2,3,4]
console.log(b)  //[2,3,4]

2)函数内获取

    function show(a, ...all) {    // 只能放最后
      console.log(a);
      console.log(all);
    }


    show(1);// 1 []
    show(1, 2, 3);// 1 [2,3]

3)数组内获取

    const [a, ...rest] = [1, 2, 3, 4, 5];
    console.log(a); // 1
    console.log(rest);// [2, 3, 4, 5]

4、数据去重

1)some()

const input = document.querySelector('input');
    const ul = document.querySelector('ul');
    const arr = [];
    render();

    input.addEventListener('keydown', function(event) {
        //判断按下的是不是回车
        if (event.key === 'Enter') {
            const isHas = arr.some((value) => value === this.value); // 在我的数组中找到了和你待添加的元素 一样的值 返回true
            if (isHas) {
                // 有重复了 不要再添加
                alert('有重复了 不要再添加');
            } else {
                // 没有重复 你可以添加
                // 把它添加到数组中
                arr.push(this.value);
                // 数组发生了改变 重新调用render方法 来实现页面的渲染
                render();
                this.value = ''
            }
        }
    });

    function render() {
        const html = arr.map((value) => `<li>${value}</li>`).join('');
        ul.innerHTML = html;
    }

六、原型链继承

利用代码的能力实现 面向对象的特性 封装继承

1、子类strudent 继承了父类 Person的属性

    // 父类
    function Person(name, height) {
      this.name = name;
      this.height = height;
    }

    Person.prototype.say = function () {
      console.log(this.name);
      console.log(this.height);
    }

    // 子类
    function Student(grade, name, height) {
      // 借用了父类的构造函数,完成对自己的赋值
      Person.call(this, name, height)
      this.grade = grade;
    }

    // 赋值了父类原型上的所有的 属性和方法
    Student.prototype = Person.prototype;
    // 修改之类的指向
    Student.prototype.constructor = Student;

    // 创建子类的实例
    const stu = new Student("一年", "周星星", 170);
    stu.say();

2、继承call

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

      function Student(name, age, height, color) {
        // 这一行代码解决了继承的问题!!
        // call 借用别人的方法
        // 谁有方法
        // 谁想要借用person方法  this = 实例 = 下面代码的s1
        Person.call(this, name, age, height);//   儿子想要复用父亲的某些代码 父亲方法.call(this,形参1,形参2。)
        this.color = color;
      }

        const p1 = new Person('奥特之父', 5000, 200);
        const s1 = new Student('迪迦', 2000, 100, 'yellow');

        console.log(p1); //Person {username: '奥特之父', age: 5000, height: 200}
        console.log(s1); // Student {username: '迪迦', age: 2000, height: 100, color: 'yellow'}

3、call借调


      const obj={
        name:"超人",
        skill(){
          console.log(this.name +" 会飞");
        }
      }
      // 超人有技能 会飞 
      const obj2={
        name:"普通人"
      };

      // 让普通人  借 一下超人的技能 skill  固定的规则 
      obj.skill.call(obj2);


七、set对象

八、class类