41、面向对象

一、对象的举例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>对象的举例</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  /*
        面向对象:就是一种编程思想,是由属性和方法组成的
        面向对象的方法:封装、继承、多态

        面向对象的特点:
            抽象:把主要特征和问题相关的特征抽离出来
            封装:看不到里面的对象,用好表面的功能
            继承:遗传,从父类继承出一些方法和属性,子类又有自己独特的特征
    */
  // js对象都是由属性和方法组成的,变量就是属性,函数就是方法
  var a = 12; // 变量是自由的 不属于任何人
  var arr = [11, 22, 33];
  arr.a = 12; // 设置属性
  console.log(arr);

  // 变量能做的事,属性也能做,属性和变量其实是一个东西,只不过变量是自由的,属性是属于一个对象的。
  // 函数就是方法
  var obj = {};
  obj.name = "张三";
  obj.age = "18";
  obj.getName = function () {
    console.log(this.name);
  };
  obj.getName();
  console.log(obj);
  /*
        等价于
            var obj = {
                name:'张三',
                age:'18',
                getNmae: function(){
                    console.log(this.name)
                }
            }
    */
</script>

二、封装函数

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>封装函数</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  var obj = {};
  // 设置属性
  obj.name = "name";
  obj.age = "age";
  // 设置方法
  obj.getName = function () {
    console.log("我的名字是" + this.name);
  };
  obj.getAge = function () {
    console.log("我的年龄是" + this.age);
  };
  /*
        等价于:
            var obj = {
                name:'name',
                age:'age',
                getName:function(){
                    console.log('我的名字是'+this.name)
                },
                getAge = function(){
                    console.log('我的年龄是'+this.age)
            }
    */
  console.log(obj);
  obj.getName();
  obj.getAge();

  // 上述方法的缺点:当我们创建多个对象的时候,重复代码太多了
  // 要进行封装,所以就有了工厂模式
</script>

三、工厂模式

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>工厂模式</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  // 工厂模式就是创建对象的一种方式(原料--加工--出厂)
  function createFn(name, age) {
    // 1.创建空白对象
    var obj = new Object(); // var obj = {}
    // 2.加工原材料(添加属性和方法)
    obj.name = name;
    obj.age = age;
    obj.getName = function () {
      console.log("我的名字是" + this.name);
    };
    obj.getAge = function () {
      console.log("我的年龄是" + this.age);
    };
    // 3.出厂
    return obj;
  }

  var obj1 = createFn("张三", 18);
  var obj2 = createFn("李四", 20);
  console.log(obj1, obj2);
  obj1.getName();
  obj2.getAge();

  // 如果创建了不同的对象 其中的属性方法会重新建立 消耗内存 所以 出现了构造函数
</script>

四、构造函数

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>构造函数</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  /*
        什么是构造函数:
            在js中用new关键字来调用的函数被称为构造函数 new Array  new Date ...

        new 在执行时会做四件事:
            1.在内存中创建一个新的空对象
            2.让this指向这个空对象
            3.执行构造函数里面的代码,给这个新对象添加属性和方法
            4.返回这个空对象(构造函数里面不需要return)
    */
  function createFN(name, age) {
    // 省去了创建空对象这一步
    // 让this指向这个空对象
    this.name = name;
    this.age = age;
    this.getName = function () {
      console.log("我的名字是" + this.name);
    };
    this.getAge = function () {
      console.log("我的年龄是" + this.age);
    };
  }
  var obj1 = new createFN("张三", 18);
  obj1.getName(); // 我的名字是张三
  var obj2 = new createFN("李四", 20);
  console.log(obj1, obj2);
  console.log(obj1.getName == obj2.getName); // false
  // 这两个对象有相同的功能,在不能说共用了一个方法,每new一次,系统会创建一个内存,两个对象各自执行各自的,这样会消耗内存
  // 如果想让两个对象共用一个方法怎么办?--原型
  /*
        构造函数和工厂模式相比,省去了创建空对象和将结果返回出去这两个步骤

        什么是构造函数?构造函数偷偷帮我们干了哪两件事?
            在js中,用new关键字调用的函数称为构造函数
                1.帮我们偷偷创建了一个空白对象
                2.替我们将结果返回出去
    */
</script>

五、原型

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>原型</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  /*
        什么是原型?
            在js中,每个对象都有一个原型(prototype),原型是一个对象,它包含共享的属性和方法 可以被其他对象继承和访问。对象可以通过原型继承属性和方法,而不是通过复制。
        
        什么是原型链?
            js中的原型链是一种通过原型链接起来的对象层级结构。每个对象都有_proto_这个属性,这个属性指向它的原型对象。原型对象也是对象,也有_proto_这个属性,指向原型对象的原型对象,这样一层一层的形成链式结构,称为原型链。当我们访问一个对象的属性和方法时,如果对象本身没有这个属性和方法,js引擎会沿着原型链向上查找。知道找到该属性或方法或者达到原型链顶部为止,如果顶层也找不到,返回null。
    */
  function createFN(name, age) {
    this.name = name;
    this.age = age;
    // 添加原型的方法
    // 将getName这个方法添加到对象的原型上
    createFN.prototype.getName = function () {
      console.log("我的名字是" + this.name);
    };
    createFN.prototype.getAge = function () {
      console.log("我的年龄是" + this.age);
    };
  }
  var obj1 = new createFN("张三", 18);
  var obj2 = new createFN("李四", 20);
  console.log(obj1, obj2);
  console.log(obj1.getName == obj2.getName); // true
</script>

六、原型求和

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>原型求和</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  var arr1 = [11, 22, 55, 66, 99, 100];
  var arr2 = [55, 2, 16, 95, 55];

  // 将sum方法添加到了Array的原型上
  Array.prototype.sum = function () {
    var result = 0;
    // this关键字指向的是调用方法的数组对象
    for (var i = 0; i < this.length; i++) {
      result += this[i];
    }
    return result;
  };
  console.log(arr1, arr2);
  console.log(arr1.sum());
  console.log(arr2.sum());
</script>

七、call&bind&apply

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>call&bind&apply</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  var bd = {
    name: "百度",
    say: function (val) {
      console.log(this.name, val);
    },
  };
  var tx = {
    name: "腾讯",
    say: function (val) {
      console.log(this.name, val);
    },
  };

  bd.say("李彦宏"); //百度 李彦宏
  tx.say("马化腾"); //腾讯 马化腾

  // 对象.属性.call('让this指向那个对象','传递的参数')
  // 在调用bd中的say方法时,让bd这个对象中的this执向tx这个对象
  bd.say.call(tx, "李彦宏"); // 腾讯 李彦宏

  // 对象.属性.apply('想让this指向的那个对象',['传递的参数'])
  bd.say("张三");
  bd.say.apply(tx, ["张三"]); // 腾讯 张三

  // bind 返回的结果是个函数
  var result = tx.say.bind(bd, "name");
  result(); // 百度 name

  /*
        call、apply、bind总结:
            相同点:call apply bind都可以改变this的指向
            不同点:
                1.call和apply会调用函数,而bind返回的是一个新的函数
                2.传参不一样,apply传的参数是数组的形式

        请说一下你对this的理解?
            在浏览器中,全局范围内this指向的是window
            在普通函数中,this指向的是当前函数的调用者
            在构造函数中,this指向的是new出来的那个新对象
            call、apply、bind中的this指向的是强制绑定的那个对象
    */
</script>

八、继承

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>继承</title>
  </head>
  <body></body>
</html>
<script type="text/javascript">
  function Animal() {
    this.category = "动物";
  }

  function Cat(name, color) {
    this.name = name;
    this.color = color;
  }
  // 怎么样能使猫继承动物中的category属性
  // 方法1 在Cat构造函数中 调用Animal这个构造函数 并且修改Animal的this指向 让它指向cat
  /*function Car(name,color){
        Animal.call(this)
        this.name = name
        this.color = color
    }
    var xm = new Cat('miqi','黑色')
    console.log(xm)*/

  // 方法2
  // constructor是js中的一个特殊属性,存在于每个对象的原型上,当创建一个对象时,js会自动为该对象添加一个constructor属性,指向用于创建该对象的构造函数
  // 将猫的原型指向一个动物的构造函数
  Cat.prototype = new Animal();
  /*
        Cat.prototype = new Animal() 将Cat.prototype设置为了Animal实例,这样会导致Cat.prototype.constructor指向Animal构造函数而不是Cat,为了确保Cat.prototype.constructor指向其正确的构造函数,即Cat构造函数,需要显示得将其设置为Cat
    */
  Cat.prototype.constructor = Cat;
  var zgc = new Cat("miqi", "黑色");
  console.log(zgc);
</script>

九、笔记

什么是面向对象?
    面向对象就是一种编程思想,是由属性和方法组成的。
面向对象的特点:
    抽象:把主要特征和问题相关的特征抽离出来
    封装:看不到里面的对象,用好表面的功能
    继承:遗传,从父类继承出一些方法和属性,子类又有自己独特的特征

工厂模式
    1.原材料
    2.加工 (添加属性和方法)
    3.出厂 (return obj)

原型:每个对象都有原型属性,我们把方法写在原型上,这样我们创建出来的对象就可以共用原型上的方法


什么是构造函数?
    在js中,用new关键字来调用的函数称为构造函数

继承方法:
    1.call/apply
    2.原型链继承
    2.利用空对象作为中介

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪花酥01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值