js高级学习

78 阅读6分钟

一面向对象

1面向对象介绍

1.1面向对象:是一种解决问题 思维方式

面向过程:注重的是过程

面向对象:注重的是结果

1.2面向对象 本质 是对面向过程的封装

2面向对象的编程举例

2.1给页面每一个div标签 和 p标签 设置颜色 和边框

//2.1获取元素
   let divList = document.querySelectorAll("div")
    let pList = document.querySelectorAll("p")
    //2.2对象封装
  let obj = {
      setColor: function (arr, color) {
        for (let i = 0; i < arr.length; i++) {
          arr[i].style.backgroundColor = color
        }
      },
      setBorder: function (arr, border) {
        for (let i = 0; i < arr.length; i++) {
          arr[i].style.border = border
        }
      }
    }
    //设置颜色
    obj.setColor(divList,'red')
    obj.setBorder(divList, '5px solid blue')
    
    //第二种方式
    
      $('div,p').css({
          backgroundColor:'red',
          border:'5px solid cyan'
      })

    

内置对象

`` /* 内置对象: js作者提前封装好的对象 */

    声明数a组
    let arr = [10,20,30,40,50]// new Array(10,20,30,40,50)

    //(1) arr.concat(数组)   : 把两个数组连接成一个数组
    //应用场景: 一般用于长列表(下一页),不断往后面拼接数组
    let newArr = arr.concat([60,70,80,90])
    console.log(newArr)

    //(2) arr.reverse()   : 翻转数组
    //应用场景: 价格从低到高 切换成 从高到低, 只需要翻转数组即可
    arr.reverse()
    console.log( arr )

    //(3) arr.join('分隔符') : 把数组每一个元素拼接成字符串
    let arr1 = [80,90,55,60]
    //应用场景 :  有些歌曲是多个人合唱,服务器会给我们一个数组。 这个时候就需要将数组元素通过join拼接起来然后再页面显示
    let str = arr1.join('&')
    console.log( str )//80&90&55&60

    //(4) arr.sort( function(a,b){return a-b} ) : 排序
    let arr2 = [80,90,50,20,77,88]
    arr2.sort( function(a,b){
        // return a-b //从小到大
        return b-a //从大到小
    } )
    console.log(arr2)
  
##字符串对象

   1. 字符串类似于数组,也有长度和下标
        // console.log( str.length )//16
        // console.log( str[5] )//武
        
   2.str.indexOf('字符串')   获取 ‘字符串’
   果字符串不存在则返回固定值 -1
        // // 应用场景: 一般用户判断 str中是否有某个字符串  如果没有则返回-1,
        
        
        
   3. str.split('分隔符')   用分隔符切割字符串,得到切割之后的数组 
        // // 应用场景 : 一般用户解析 网址
         let url = 'http://www.baidu.com?name=张三&age=20'
         console.log( url.split('|') )//['http://www.baidu.com?name=张三&age=20']
         console.log( url.split('?') )//['http://www.baidu.com', 'name=张三&age=20']
         console.log( url.split('=') )//['http://www.baidu.com?name', '张三&age', '20']
        
        
  4. str.substr(起始下标,截取长度) 
     一般后台返回的数据 不会和前端完全匹配。 有时候需要自己截取一部分
      console.log( str.substr(2,5) )//从2下标开始,往后截取5个字
      
      
   5.大小写转换 (中文没有大小写)
   /应用场景: 字母验证码不区分大小写 (一般无论你输入什么,都会转成大写或小写保持格式统一)
   console.log('dsSFJSGDJHsdfs'.toLocaleLowerCase() )//小写 dssfjsgdjhsdf
  console.log('dsSFJSGDJHsdfs'.toLocaleUpperCase() )//大写 DSSFJSGDJHSDFS
        

工厂函数

3.1需求创建很多个对象(姓名,年龄,性别) 工厂函数:用于创建对象函数

//创建一个对象
let p={}
//给对象赋值
p.name=nmae
p.age=age
p.sex=sex
//返回这个对象
return p
}
//实列对象
let p1=CreatePerson('张三',20,'男')
let p2=CreatePerson('李四',20,'男')
console.log(p1,p2)

构造函数

1工厂函数 用于创建对象的函数 2构造函数“使用new调用函数 构造函数作用与工厂函数一直,都是来创建对象的,但是代码更加简洁

3构造函new工作原理 (1)创建空对象 (2)this指向这个对象 (3)对象赋值 (4)返回这个对象 4构造函数new在使用需要注意的地方 4.1构造函数首字一般是大写,为了提醒调用者不要忘记new关键字 4.2如果在构造函数内部,手动return return 值类型:无效,还是返回new创建对象 return 引用类型:有效 会覆盖new创建的对象

            //  创建对象 {}
            // this 指向这个对象
            // 对象赋值
             this.name=name
             this.age=age
             this.sex=sex
            //  return [20,30,50]
            //  返回这个对象
         }
        let p1= new Person('张三',20,"男")
        console.log(p1)


        function Person(name,age){
            this.name = name
            this.age = age
            this.eat = function(){
                console.log('eat');

            }
        }

        let p1 = new Person('张三',18)
        let p2 = new Person('李四',20)
        console.log( p1,p2)
        
        
        
         /* 思考: p1和p2都有eat方法,而是函数体相同。但是他们是同一个函数吗?
      不是同一个: 因为每一次调用构造函数, 内部都会执行一次function,就会在堆中开辟一个新的空间。虽然代码是一样的,但是地址不同。 就会导致每调用一次构造函数,多出一个函数堆空间。导致内存资源浪费
      */
      //   console.log( p1.eat == p2.eat )//false


   /* 2.使用全局函数解决内存浪费 值类型 应用类型
      导致新的问题: 全局变量污染
      
         
      */
        let eat = function() {
          console.log("吃东西")
        }

        let learn = function() {
          console.log("学习")
        }

        function Person(name, age) {
          this.name = name
          this.age = age
          this.eat = eat 
          this.learn = learn
        }

        let p1 = new Person("张三", 18)
        let p2 = new Person("李四", 20)
        console.log(p1, p2)
        
        
        
        
      /* 3.使用对象 : 解决内存浪费 + 变量污染 */

      let obj = {
        eat: function() {
          console.log("吃东西")
        },
        learn: function() {
          console.log("学习")
        }
      }

      function Person(name, age) {
        this.name = name
        this.age = age
        this.eat = obj.eat
        this.learn = obj.learn
      }

      let p1 = new Person("张三", 18)
      let p2 = new Person("李四", 20)
      console.log(p1, p2)
         

原型对象

原型是属性

1原型对象是什么?任何函数在声明的时候,系统会自动帮你创建一个对象,称之为原型对象 2原型对象的作用?解决 内存浪费 +变量污染 3.原型对象相关三个属性 : 描述 构造函数、原型对象、实例对象三者关系

        prototype :  属于构造函数, 指向原型对象
        
        
        __proto__ :  属于实例对象,指向原型对象
        
        
        constructor : 属于原型对象,指向构造函数
prototype :  属于构造函数, 指向原型对象
      function Person(name, age) {
        this.name = name
        this.age = age
      }

      //原型对象
      console.log(Person.prototype)
      Person.prototype = {
        eat: function() {
          console.log("吃东西")
        },
        learn: function() {
          console.log("学习")
        }
      }

      //实例对象 : 用new调用构造函数,返回的那个对象(new创建的那个对象)
      let p1 = new Person('张三',20)
      console.log( p1 )

      let p2 = new Person('李四',22)
      console.log( p1.eat == p2.eat )//true
      

        __proto__ :  属于实例对象,指向原型对象
    
        //1.构造函数
        function Person(name,age){
            this.name = name
            this.age = age
        }

        //2.原型对象
        Person.prototype.eat = function(){
            console.log('吃东西')
        }

        Person.prototype.learn = function(){
            console.log('学习')
        }

        //3.实例对象
        let p1 = new Person('张三',20)
        console.log(p1)

        /* 为什么实列对象可以直接访问原型中的成员 本质是通过_ proto_来访问的
        __proto__ : 属于实例对象的,指向原型对象
        注意: 这个属性不是web标准,很多浏览器不会显示的。 这个属性在开发中不能使用,只能用于学习研究
        */
       console.log(p1._proto_)
        p1.eat()//p1.__proto__.eat()
        // console.log(p1._proto_===Person.prototype)
        
      
```  //1.构造函数
        function Person(name,age){
            this.name = name
            this.age = age
        }

        //2.原型对象
        Person.prototype.eat = function(){
            console.log('吃东西')
        }

        Person.prototype.learn = function(){
            console.log('学习')
        }

        console.log( Person.prototype.constructor )//Person
        
     constructor : 属于原型对象,指向构造函数
        let p1 = new Person('张三',20)
        console.log(p1)
        let p2=new Person('李四',20)
        console.log(p2)

        /* __proto__ : 属于实例对象的,指向原型对象
        注意: 这个属性不是web标准,很多浏览器不会显示的。 这个属性在开发中不能使用,只能用于学习研究
        */
        p1.eat()//p1.__proto__.eat()
        p2.learn()

        /* 验证 构造函数、原型对象、实例对象三者关系 */
        console.log( p1.__proto__.constructor )//Person
        console.log( Person.prototype === p1.__proto__ )//true
              

静态成员

       静态成员:  函数的属性
       实例成员:  实例对象的属性
       */
       function Person(name,age){
           this.name = name
           this.age = age
       }

       let p1 = new Person('张三',20)
       console.log( p1.name )//实例成员
       console.log( p1.age )//实例成员

       console.log( Person.prototype )//静态成员
       console.log( Math.PI ) //静态成员
       

Object的values方法

         let person = {
             name:'张三',
             age:20,
             sex:'男'
         }

         //1 以前的写法:  for-in 循环
         for(let key in person ){
             console.log( person[key] )  
         }

         //2.静态方法  Object.values(对象名)
         //返回值是一个数组,会存储对象每一个属性值
         let arr = Object.values(person)
         console.log(arr)

        //  object静态方法 Object.values(对象名)
        console.log(Object.keys(obj))
        console.log(Object.values(obj))