认识 js高级

119 阅读10分钟

认识高级js

函数箭头

匿名函数可以 用函数箭头表示,函数箭头写法简单,比较优雅

let text = function (){
}
这是普通匿名函数写法 
let text = ()=>{
}
这是箭头函数写法 省略了 function1.如果函数体只有一句,那么可以省略{},同时默认会返回函数体的结果,不能写return
2.如果只有一个参数,那么可以省略()
3.如果没有参数,()也不能省略 
let test = (a,b) =>  a + b    // 不能有大括const ter = (num)=> num +100
console.log(ter)
将上一句代码和下面的代码进行相加
let res = test(100)
console.log(res);
结果是200

forEach遍历

const arr = ['a','b','c']
forEach 正常写法
arr.forEachfunction (){
console.log(`值是 ${value} 索引是${index}`)
)
箭头函数简写写法
arr.forEach((value,index)=>console.log(``值是${value} 索引是${index} ``))

map数组常用方法

map 方法 表示 把一个旧的数组 ,重新组装成一个新得数组

map()
function map(){
    const arr = ['我自己','你自己','她']
    const arr1 = [1,2,3,4,5]
    const newArr = arr.map(value =>{
    console.log(`爱` value)
    输出结果为 [爱我自己,爱你自己,爱她]
    const str = arr.map(value => value +1)
    输出结果为 [2,3,4,5,6]
    })
}
​
 map()
function map(){
    const arr = ['a','b','c']
    const arrtex = arr.map(value => ({name:value}))
            // 箭头返回值 ,表示 返回 三个 对象 数组 因为加了{}
    console.log(arrtex);
 }

every数组常用方法

every 是一个数组方法 ,伪数组不能使用,转换成真正的数组就能用

这个方法 是比较 只有 数组 里面全部 比较为 true ,才 返回true

every 只能返回 true 或者 false

要求数组里面每一个元素都符合条件,为true,才会返回true,类似于&&与运算

注意!!!如果空的数组调用了eveny,得到的结果也是为true

 function every(){
            const arr = [1,3,5,7]
            const arrTs = arr.every((value) =>{
 // arr.every表示选中 arr数组 ,使用every方法 ,value代表的是arr数组里面的值
           if(value < 8){
                  return true    
                }else{
                    return false
                }
            })
          console.log(arrTs);
        }
        every()
比较数组里面的值 全部为true 才返回ture

伪数组转数组方法

伪数组转 数组 用 这样一个 方法 很简单

接收元素 = [...伪数组]

filter数组常用方法

  filter()
       function filter(){
        //    fliter 数组方法就是 过滤掉你不想要的 ,然后 需要的 会自动 创建一个
        //    新的数组 和 js基础 % 类似
        const arr = [1,2,3,4,5,6,7,8,9]
        const arrIn = arr.filter(value => value % 2 !== 0)
        console.log(arrIn);
       }

some数组常用方法

/*  some 的意思就是 只要有  一个 条件满足 则返回 true  和逻辑或||相似
        而 every 就是 全部 为true 才返回true 或 逻辑与|| 相似 */
        function some(){
            const arr = [1,2,6,9,3,5]
            const arrIn = arr.some(value => value > 8)
            console.log(arrIn);
        }

字面量函数

  // 字面量  创建对象不方便维护 因为要修改属性还得一个一个修改
  // 假如现在我想要修改name属性 修改成userName  处理起来就比较麻烦
 let obj1 = {
            name:'我自己',
            height: 167,
        }
        let obj2 = {
            name:'我自己',
            height: 167,
        }
        let obj3 = {
            name:'我自己',
            height: 167,
        }

工厂函数

  // 工厂函数,createperson
  // 工厂函数 有点是 方便复用 ,缺点是无法继承 一样的属性名 一样的样式 爸爸和儿子
        // 儿子 继承 不到 爸爸的 样式
        function createPerson(name,age,height){
            return {
            names:name,
            ages : age,
            heights : height
            }
        
        }
        const obj1 = createPerson('孙悟空',18,150)
        console.log(obj1);
        
        const obj2 = createPerson('沙和尚',18,150)
        console.log(obj2);
        
        const obj3 = createPerson('猪八戒',18,150)
        console.log(obj3);

构造函数

function createPerson(name,height){
            this.name = name,
            // 构造函数 必须是 this.xxx =
            this.height = height
        }
        const obj1 =new createPerson('我自己',22)
        // 传实参到形参必须 要以 new 开头,加上函数名字
        console.log(obj1);
        console.log(obj1.name);

构造函数性能问题

    // 构造函数 优点  复用方便 拥有继承性 还有很多优势
    // 专业术语
    // createPerson() 叫做构造函数
    // new createPerson () 叫做 实列
    function createPerson(name,age,height){
        this.name = name;
        this.age = age;
        this.height = height;
    }
    const obj1 = new createPerson('她',18,155)
    // 必须要通过 一个 new方式 来创建 对象
    console.log(obj1);
    console.log(obj1.name);

构造解决性能问题

        function CreatePerson(name,say) {
            this.name = name
            this.say = say
        }
        const obj1 = new CreatePerson('孙悟空')
        const obj2 = new CreatePerson('猪八戒')
        //   console.log(obj1.say===obj2.say);
        //   console.log();
        //   1  obj1.say ==obj2.say,两个比较是为false,因为
        //   我们每创建一个对象,都会开辟一个新的内存地址,两个比较是为false内存地址
        //   都不一样 所以返回结果为false,内存消耗比较大,性能自然而然就不那么好了
​
        console.log(obj1.say === obj2.say);
    // 2  解决构造函数性能问题 ,想要解决性能问题 ,我们只需要把say方向变成全局变量
    // 让每一次创建新的对象的时候,this指向都会指向我们构造函数外面的say方法,
    // 因此,全局变量的say方法,我们无论创建多少个对象,就会一起存放到全局变量say
    // 方法里面

构造函数 污染全局变量

 // 如果函数方法 作为全局变量 也会污染全局变量,
    // 因为一个大型项目当中,你不可能记得你用了哪个
    // 方法,然后如果你下面设置的方法刚好和上面的方法
    // 函数一样,机会覆盖掉,就会出错
        function say(){
            console.log('你吃饭了吗');
        }
      function CreatePerson(name){
          this.name = name
          this.say = say
      }
      const obj1 = new CreatePerson('孙悟空')
      const obj2 = new CreatePerson('猪八戒') 
      console.log(obj1.say === obj2.say);// 如果为true 表示优化过的
      console.log(obj1.say === obj2.say);// 如果为false 表示没有优化过的
    // 函数作为全局变量 方法 提取出去 
    /* 优点 : 方便复用 代码维护 也解决了 性能 obj1.say ===obj2.say 只要
           两者相等,就可以说是解决了性能问题了,因为两个对象都存储到一个
           内存地址上了 */

原型对象 最终选择

// 原型对象可以很好的帮我们解决了 姓名 全局变量污染 的问题
        // 原型对象prototype 才是最终要选择用的一个方法

        // 原型对象 是任何构造函数对存在的一个对象 prototype
        // 作用: 构造函数看是人, 原型对象 就是人的DNA
        // 如果我们修改了DNA,那么通过构造函数创建实例都会一起发生修改
        // 如果我们在DNA上新增了一些东西,对应实例一样会被新增
        function CreatePerson(name){
            this.name = name
        }
        CreatePerson.prototype.i= ()=>{
            console.log('你吃饭了吗?');
        }
        
        const obj1 = new CreatePerson('悟空')
        const obj2 = new CreatePerson('八戒')
       
        console.log(obj1.i()===obj2.i()); // 等于true  没有性能问题
        // 有污染全局变量的问题吗  没有
        // 小结 原型对象-构造函数 一般情况 
        // 构造函数内只放属性 name 、age、color、height
        // 对应原型上 都是放 方法 = 函数

原型继承

        // 这个就是 ii函数 借调 cc函数里面的 属性
​
        // 假如是 我们想借调 cc 里面的属性 ,原理就是 谁借用他,那个方法就属于谁的
        // 我们ii 借调cc 函数属性 ,只需要在 ii 函数里面 写上 借调函数名.call
        //  (this,表示当前函数借调,再添加上 想要借调的属性名 name age height)
        function cc(name,age,height){
            this.uname = name
            this.age = age
            this.height = height
        }
        function ii(name,age,height,color){
            cc.call(this,name,age,height)
            // 这一行代码解决了 继承问题 
            this.color = 'red'
            // 借调函数里面没有color 这个属性,所欲说我们要自己创建
        }
        const obj = new cc('我自己',22,167)
        
        const obj1 = new ii('梁祺星','22岁',167,'red')
        console.log(obj1);
        梁祺星 22167 red
        console.log(obj);
        输出结果为 我自己 22 167

属性方法继承

  function Person(name, age) {
            this.username = name;
            this.age = age;
        }
​
        Person.prototype.say = function () {
            console.log(this.username, this.age)
                ; // 我是谁 我的年龄是
        };
        //  const p1 = new Person('我',19)
        //  console.log(p1.say());
        //  如果是输入 say方法的话  只会输出 父元素的值
​
        // Person.prototype.say = function () {
        //     console.log(this.username1, this.age)
        //     ; // 我是谁 我的年龄是
        //   };
        Person.prototype.show = function () {
            console.log(this.username + ' 秀肌肉');
        };
​
        function Student(name, age, color) {
            Person.call(this, name, age)
            this.color = 'red'
        }
        const s1 = new Student('梁', 22, 'green')
        Student.prototype.say = Person.prototype.say
        Student.prototype.show = Person.prototype.show
        s1.say()
        输出结果为 梁 22
        s1.show()   
        输出结果为 梁 秀肌肉
​

函数参数默认值

  function cc(mag = '你好', i = '我号') {
            console.log(mag, i);
        }
          cc('大家好')
         输出结果为 大家好
          要是我们没有进行 调用函数 没有 传实参,那么他就会 输出一个你好,
          要是我们 传了实参,那么 输出的就是我们的实参  相当于进行了判断 
          cc('我很好', '她也很好')
          要是我们 只传了一个 实参 ,有两个 属性 ,另外一个就会显示默认属性 i
          如果有两个 属性 ,没有 传参 就会输出 自定义属性的值

对象简写

  /* 对象属性方法 简写 
        如果变量名和 对象属性一致 ,则可以 直接在 对象大括号里面输入变量名
        就可以 得到 变量名得值 */
        const name = '你好'
        const age = '22岁'
        const obj = {
            name,
            age
        }
        console.log(obj);
          输出结果为  name :你好  age : 22岁
​
        const obj1 = {
             say = function(){
​
             }
               可以进行简写 
            say() {
​
            }  这样就可以简写了
​
        }

解构

<div data-index = '100'></div>
    <script>
        const {index} = document.querySelector('div').dataset
        console.log(index);
        // 简写属性
​
        const arr =[ '猪八戒','白龙马','孙悟空','小乔']
        // 希望 声明四个变量  a = 悟空  b = 八戒 
        // 数组解构
        const [a,b,c,d] = arr
        console.log(a,b,c,d);
        // 相当于是
        // const [a, b, c, d] = ['悟空', '八戒', '龙马', '三藏',"沙僧"];
        const obj ={
            name:'悟空',
            age: 18,
            height:167
        }
        // 对象解构
        // 声明三个变量来接收obj得三个属性
        const {name,age,height} = obj
        console.log(name,age,height);
        // 简写属性
    </script>

拓展运算符

 // ...表示获取剩下 的 数组
        // const arr = [1,2,3,4,5,6]
        // const [a,b,...c] = arr
        // console.log(a,b,c);// a 和b 对应数组的里面的内容,c就是取剩下组成一个新的数组
        // 输出 1 2 [3,4,5,6]
​
        // 获取剩下的 对象
        // const {a,...c} = {a:1,b:2,c:3}
        // console.log(a,c);// a  对应数组的里面的内容,c就是取剩下组成一个新的对象
        // 输出 a:1 {b:2,c:3}
​
         /* const [...a] =[1,2,3,4]
         console.log(a) //输出结果是 1 2 3 4
         console.log(a.map);
         //  ...args延展符 有数组 功能 */
​
        //  计算一个和
​
        function call(...args){
            let sum = 0
            args.forEach(value => sum += value);
            console.log(sum);
        }
        call(1,2,3,4,5)
​
​
        // 剩余运算符
       /*  1 数组中 const [a,b,...c] = [1,2,3,4,5,6,7] a是1 b是2 c是一个数组 [34567]
          应用场景 把伪数组转成真正的数组
        
        2 对象中 const {a,...c} = {a:1 b:2 c:3} a是1  c是 {b:2 c:3}
          
        3 函数的形参中 function calc(...args) 等于 {args[1,2,3]}
​
        calc(1,2,3) */

拓展 展开 延展

 const obj ={
            username : '悟空',
            age : 18
        }
        // 展开 ...用法
        // 新创建一个对象,这个对象拥有obj所以的属性
       
        // ...延展 表示 把 obj里面的 属性延展开 然后拿到obj里面的属性
        // 可以添加属性color
        const obj1 = {...obj,color:'yellow' }
         // 同时并且加多color:"red"属性
        console.log(obj1);
        // 输出结果为 username: '悟空', age: 18, color: 'yellow'}

展开运算符

// 展开运算符
        /* const obj1 = {
            name:'梁',
            age : 18,
            hieght :167
        }
        const obj2 = obj1
        obj2.color = 'red'
        console.log(obj1);新的对象
        console.log(obj2);旧的对象
        对象是引用类型 */
        /* 写 =  将 obj2的地址 给了一份 Obj1  两个变量指向的地址同样的 同一个对象
        这样直接赋值方法是错误的,我们修改了值 ,两个对象的值都会改变
        因为内存地址是同一个 */

set对象数组

/* Set.add 可以去重,如果你添加的内容已经是有的,那么 再用Set.add添加
        将不会有结果,Set.add就是去重,es6 自带的去重效果 */
        let arr = ['b','a','c',1,2]
        const newArr = new Set(arr)
        // new Set 方法可以将一个数组转换成 一个对象
        newArr.add(3)
        // 给对象添加 值 3
        newArr.add(4)
        const isn = [...newArr]
        // 把newArr转换成数组 赋值给 isn
        console.log(isn);
        // 输出结果是 数组 b a c 1 2 3 4

band call apply 继承传参

 // 继承方法 并传参数
        const obj = {
            name: '大朗',
            say(a, b) {
                console.log(this.name + ' ' + a + ' ' + b);
            }
        }
        const person = {
            name: '西门大官人'
        }
        obj.say.call(person, 1, 2)
        // call传参数 直接 对象名 加 参数 1  参数2

        obj.say.apply(person, [1, 3])
        // apply 直接 对象名 加 数组,把参数放进数组里面
        const i = obj.say.bind(person)
        // bind 直接 对象名 ,然后会返回一个函数返回值的,需要我们
        // 自己调用 参数 直接放在 调用函数的括号 i(参数1,参数2)
        i(1, 4)

this指向

        // 谁借调 方法 this 就指向谁
        const obj = {
            name: '老王',
            say() {
                console.log(this.name + ' 翻墙');
            }
        }
        const person = {
            name: '大朗'
        }
        obj.say.call(person)
        //  all 方式来修改this的指向
        // obj.skill.call(person);// 大郎 借用老王的方法
        obj.say.apply(person)
        //  apply 方式来修改this的指向
        // obj.skill.apply(person); // 大郎 借用老王的方法
        const fun = obj.say.bind(person)
        fun()
      /*   bind 方式修改this指向 不过他不会给你输出 数据
              而是给你一个函数返回值 ,你还要 创造一个变量来接收
              这个函数返回值 然后 调用 */

es6面向对象 语法结构

  // es6 面向对象写法  看到class就知道是 面向对象了
        class person {
            // constructor是固定写法 ,把属性都写在constrctor里面
            constructor(name) {
                this.name = name
            }
            // 把方法都写在say里面就好了
            say() {
                console.log(this.name + ' say方法被调用啦');
            }
        }
        const obj = new person('悟空')
        const obj1 = new person('八戒')
        obj.say()
        // 输出结果为 悟空 say方法被调用啦
        obj1.say()
        // 输出结果为 八戒 say方法被调用啦

es6 继承 父元素 属性 方法

 class person {
            constructor(name) {
                this.name = name
            }
            say() {
                console.log('翻墙 ' + this.name);
            }
        }
        class person1 extends person {
            // class是固定写法 person1是 函数名 extends 是继承 person 符元素
            // 相当于 person1 继承 父元素 的属性 和属性值
            constructor(name) {
                // 写了 constructor 必须要写 super

                super(name)
                // 在es6直接 super(要继承的属性) 就可以了
                // super在es5 表示 person.call(this.name)
            }
        }
        const obj1 = new person1('梁祺星')
        /*  父元素没有数值型,所以我们手动
         添加一个属性值上去 */
        console.log(obj1);
        obj1.say()
        // 输出结果 是 梁祺星 翻墙

es6 三种定义方法

class person {
            constructor() {
                //    this.name = name,
                //    this.age = age,
                //    this.height = height
            }
            //    say(){}定义方法 最性能最好的 而且不会全局污染
            say() {
                console.log('say');
            }
            // 不推荐
            say1 = function () {
                console.log('say1');
            }
            // 不推荐
            say2 = () => {
                console.log('say2');
            }
        }
        const a1 = new person()
        const a2 = new person()
        console.log(a1.say === a2.say); true
        console.log(a1.say1 === a2.say1); false
        console.log(a1.say2 === a2.say2); false

\