面向对象(为达到结果不择手段)

146 阅读7分钟

01-面向对象

1.面向对象是注重结果的思维方式

面向过程: 注重过程.

举例:吃火锅-买食材-买锅电磁炉-煮熟开吃

弊端:(1)代码冗余:相同代码重复使用 (2)维护不便

面向对象: 注重结果

举例:点外卖

2.面向对象与面向过程的关系

面向对象本质: 面向过程的封装

封装: 把代码放入对象的方法中

直接放入函数中: 功能过多就会导致全局变量污染

02-面向对象编程案例

02-内置对象api

学习传送门:https://www.runoob.com/jsref/jsref-obj-array.html

内置对象: JS作者提前封装好的对象

    • api : 预先定义的函数
  • 学习内置对象: 不需要死记硬背,忘记了随时查阅文档。 用多了自然就记住了,熟能生巧

1.1-数组对象api

/*1.数组的增删改查操作

新增元素到最后面 : arr.push( 元素 )

新增元素到最前面 : arr.unshift()

删除最后一个元素 : arr.pop()

删除第一个元素 : arr.shift()

删除指定位置元素 : arr.splice(起始下标,删除数量)

*/

join()把数组的所有元素放入一个字符串。
reverse()反转数组的元素顺序。
sort()对数组的元素进行排序。

2.将数组中的每一个元素都拼接成一个字符串

let str = arr .join( )//10,20,30

3.翻转数组

var newArr = arr.reverse()

4.arr2.sort(function (a, b) {

return b - a//从大到小

})

console.log(arr2)

//声明数组
        let arr = [10, 20, 30, 40, 50]
        // 1.  arr.concat(数组) :把两个数组链接成一个数组
        //应用场景:一般用于长列表(下一页),不断往后面拼接数组
        let newArr = arr.concat([60, 70, 80, 90])
        console.log(newArr)
        
        arr.reverse()
        //应用场景:价格从低到高切换成从高到低, 只需要翻转数组即可
        console.log(arr)


        let arr1 = [80, 90, 55, 60]
        let str = arr1.join('|')
        //应用场景:有些歌曲多人合唱,服务器会给我们一个数组,这个时候就需要用join拼接起来在页面显示


        console.log(str)//80|90|55|60


        let arr2 = [80, 90, 50, 40, 20, 70]
        arr2.sort(function (a, b) {
            return b - a//从大到小
        })
        console.log(arr2)

(1)arr.concat(数组) : 把两个数组连接成一个数组.

//应用场景: 一般用于长列表(下一页),不断往后面拼接函数

let newArr =arr.concat([60,70,80,90)]

(2)arr.reverse() ;翻转数组

应用场景

1.2-字符串对象api

indexOf()搜索数组中的元素,并返回它所在的位置。
toLowerCase转为小写
toUpperCase转为大写
let arry = str3.split("&")//以&符号分隔字符串 [我,爱,你]
str2 = str.replace第一个参数:要修改的字符串 第二个参数:修改后的字符串
let str = "江城武汉是英雄的城市!";

//1 判断一个字符串在不在某个字符串里面

let index1 = str.indexOf("武汉")//如果存在,则返回参数字符串首字母所在的下标

let index2 = str.indexOf("城")

let index3 = str.indexOf("武城")//如果不存在,则返回 -1

console.log ( index1, index2, index3 )//0,6,-1

//2 截取字符串 第一个参数:从哪个下标开始截取 第二个参数:截取的长度

let str1 = str.substr(2,5)//武汉是英雄

console.log ( str1 )

//3 修改字符串 第一个参数:要修改的字符串 第二个参数:修改后的字符串

let str2 = str.replace("江城","大江大河大")

console.log ( str2 )//大江大河大武汉是英雄的城市!

//4 分隔字符串:将字符串按照指定的符号分隔,得到一个数组

let str3 = "我&爱&你"

//这个函数的返回值一定是一个数组

let arry = str3.split("&")//以&符号分隔字符串 [我,爱,你]

console.log ( arry )// [我,爱,你]

//5 大小写转换 (只有英文才有大小写,中文不存在大小写)

console.log ( "AKlkshflsLKJHDHL".toLowerCase () )//转为小写 aklkshflslkjhdhl

console.log ( "AKlkshflsLKJHDHL".toUpperCase () )//转为大写 AKLKSHFLSLKJHDHL

console.log ( "中文不存在大小写".toLowerCase () )//转为小写

03-原型对象

1.1.1-了解工厂函数

工厂函数:用于批量创建对象的函数

//1.需求:创建3个人对象 (姓名name,年龄age,性别sex)
      //弊端:(1)代码冗余  (2)维护不便
      // let person1 = {
      //     name:'ikun',
      //     age:32,
      //     sex:'男'
      // }


      // let person2 = {
      //     name:'班长',
      //     age:38,
      //     sex:'男'
      // }


      // let person3 = {
      //     name:'王悦',
      //     age:28,
      //     sex:'男'
      // }


      //2.使用函数创建对象 : 解决创建多个对象代码冗余
      //工厂函数 : 
      function createPerson (name, age, sex) {
        //(1)创建空对象
        let p = {}
        //(2)对象赋值
        p.name = name
        p.age = age
        p.sex = sex
        //(3)返回创建好的对象
        return p
      }


      let p1 = createPerson('ikun', 32, '男')
      let p2 = createPerson('班长', 38, '男')
      let p3 = createPerson('王悦', 28, '男')
      console.log(p1, p2, p3)

1.1.2-重点构造函数==

1.工厂函数(了解) : 用于创建对象的函数

2.构造函数 : 使用new调用一个函数

构造函数作用与工厂函数一致,都是用来创建对象的。但是代码更加简洁。

3.构造函数new工作原理

(1)创建空对象

(2)this指向这个对象

(3)对象赋值

(4)返回这个对象

4.构造函数new在使用时需要注意的地方

4.1 构造函数首字母一般大写, 为了提醒调用者不要忘记new关键字

4.2 如果在构造函数内部 手动return

return 值类型 : 无效,还是返回new创建的对象

return 引用类型 : 有效,会覆盖new创建的对象

 function Person(name,age,sex){
            //(1)创建空对象   {}
            //(2)this指向这个对象  this = {}
            //(3)对象赋值
            this.name = name
            this.age = age
            this.sex = sex
            //(4)返回这个对象 return this
        }


        let p1 = new Person('张三',20,'男')
        console.log(p1)

原型对象01(构造函数资源浪费)

1.原型对象是什么? : 任何函数在声明的时候,系统会自动帮你创建一个对象,称之为原型对象

2.原型对象作用? : 解决 内存浪费 + 变量污染

3.原型对象相关三个属性 : 描述 构造函数、原型对象、实例对象三者关系

prototype : 属于构造函数, 指向原型对象

proto : 属于实例对象,指向原型对象

  • 原型:任何构造函数在被创建的时候,系统都会自动帮我们创建一个与之对应的对象.
    • 同时解决内存浪费与全局变量污染的问题
  • 谁可以访问原型对象中的成员(属性和方法)
    • 构造函数自身:构造函数名.prototype
    • 构造函数实例化的每一个对象:点语法直接访问
 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)

原型对象02(原型对象)

//构造函数
      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

1.3- __proto__属性介绍

  • 1.属于对象,指向实例化这个对象的构造函数对应的原型

  • 2.proto属性不是W3C的标准属性,所以实际开发中一般不会使用它来访问原型

  • developer.mozilla.org/zh-CN/docs/…

  • 往原型添加属性方法,最好使用构造函数来访问构造函数名.prototype

  1.prototype属性: 属于构造函数,指向原型对象
            * 作用: 解决构造函数资源浪费+变量污染
        2.__proto__属性: 属于实例对象,指向原型对象
            * 作用: 可以让实例对象访问原型中的成员
        */


      //1.构造函数
      function Person (name, age) {
        this.name = name
        this.age = age
      }


      //2.原型对象
      Person.prototype.eat = function () {
        console.log('我中午真的吃了红烧武昌鱼')
      }
      Person.prototype.country = '中国人'


      //3.实例对象
      let p1 = new Person('班长', 28)
      console.log(p1)


      /* 
      __proto__ : 属于实例对象,指向原型对象
      */
     console.log( Person.prototype === p1.__proto__ )//true


     //实例对象为什么可以直接访问原型中的成员,其实都是通过__proto__来访问的
     /* 
     1.虽然实例对象可以直接访问原型的原理是 __proto__,但是开发中不推荐使用
     2.原因: __proto__不是ECMA标准语法,有一些浏览器不支持。
     3.结论: 学习阶段,学习原型可以用__proto__. 实际开发中,建议省略__proto__
     */
     p1.eat()//p1.__proto__.eat()

1.4-constructor属性介绍

  3.constructor: 属于原型对象,指向构造函数
            * 作用: 可以让实例对象 知道自己被哪一个构造函数创建的
        */


      //1.构造函数
      function Person (name, age) {
        this.name = name
        this.age = age
      }


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


      //3.实例对象
      let p1 = new Person('布丁', 3)
      p1.eat()
      console.log(p1.type)


      /* 
      constructor : 属于原型对象,指向构造函数
        作用:可以让实例对象知道自己被那个构造函数创建的
      */
      console.log(Person.prototype.constructor)//Person
      console.log(Person.prototype.constructor === Person )//true
      console.log( p1.constructor )//Person p1.__proto__.constructor

1.5-静态成员与实例成员

 构造函数也可以有自己的属性: 例如prototype


        静态成员 : 属于函数对象的成员
        实例成员: 属于实例化对象的成员
         */


        //构造函数
         function Person(name,age){
            this.name = name;
            this.age = age;
        };


        Person.aaa = '啊啊啊';
        console.log(Person.aaa);//静态成员
        


        //实例化对象
        let p1 = new Person('张三',20);


        console.log(p1.name);//实例成员
        console.log(p1.age);//实例成员