JS进阶3之(面向对象 封装 构造函数 原型对象 原型继承 原型链)

JS进阶3之(面向对象 封装 构造函数 原型对象 原型继承 原型链

一、面向对象

  • 面向对象编程是一种程序设计思想,它具有 3 个显著的特征:封装、继承、多态。

1.1 封装

  • 封装的本质是将具有关联的代码组合在一起,其优势是能够保证代码复用且易于维护,函数是最典型也是最基础的代码封装形式,面向对象思想中的封装仍以函数为基础,但提供了更高级的封装形式。

1.1.1 命名空间

  • 以往以普通对象(命名空间)形式封装的代码只是单纯把一系列的变量或函数组合到一起,所有的数据变量都被用来共享(使用 this 访问)。
 // 普通对象(命名空间)形式的封装
  let beats = {
    name: '狼',
    setName: function (name) {
      this.name = this.name;
    },
    getName() {
      console.log(this.name);
    }
  }
  beats.setName('熊');

1.1.2 构造函数

  • 构造函数相当于一个模板 能够像字面量那样创建出对象来
  • 所不同的是借助构造函数创建出来的实例对象之间互不影响
  • 构造函数体现了面向对象的封装特性
  • 构造函数实例创建的对象彼此独立、互不影响
  • 命名空间式的封装无法保证数据的独立性
 function Star(uname, age) {
            this.uname = uname
            this.age = age
            this.sing = function () {
                console.log('唱歌');
            }
        }
        //方法造成空间浪费
        let ol1 = new Star('刘德华', 30);
        let ol2 = new Star('周星驰', 28);

1.1.3 原型对象

  • 每一个构造函数都由prototype(原型)属性
  • prototype称为构造函数的原型对象
  • 每个原型对象都有constructor属性 代表改原型对象所对应的构造函数
    在这里插入图片描述
 		function Person(uname, age) {
            this.uname = uname
            this.age = age
        }
        //原型对象 :构造函数的一个属性(函数的一个属性),prototype
        //构造函数的propotype属性指向了一个对象 我们把这个对象称为原型对象或者原型
        //每一个构造函数都有这个属性
        //作用 存储(共享)方法,节省内存
        //当实例对象找不到成员的时候就会找原型对象上的成员
        //Person为构造函数
        Person.prototype.sing = function () {
            console.log('唱歌');
        }

        console.log(Person.prototype);
        let obj = new Person('阿飞', 22);
        console.log('obj', obj);
        obj.sing()  //实例对象可以使用
  • 当访问对象的属性或方法时,先在当前实例对象是查找,然后再去原型对象查找,并且原型对象被所有实例共享。
		function Person(uname, age) {
            this.uname = uname
            this.age = age
            this.sing = function () {
                console.log('构造的sing方法');
            }
        }
        Person.prototype.sing = function () {
            console.log('原型对象');
        }
        console.log('构造函数', Person, Person.prototype);
        let obj = new Person('唱歌', 24);
        //自己有就用自己的 没有就用原型对象的
        console.log('实例化对象', obj.sing);
  • 每一个原型对象都有一个属性 constructor:用于指回构造函数本身
 		function fn() {
            console.log('构造函数');
        }
        console.log(fn.prototype.constructor);
        //constructor 用于指向构造函数本身

        function Person(uname, age) {
            this.uname = uname
            this.age = age
        }
        //实例化对象
        let obj = new Person('阿飞', 22);
        console.log('实例对象', obj.constructor);
  • 每一个实例对象都有一个属性:__proto__(隐形原型) ===Person.prototype
		function Person(uname, age) {
            this.uname = uname
            this.age = age
        }
        //原型对象
        Person.prototype.sing = function () {
            console.log('原型对象', Person);
        }
        //实例对象
        let obj = new Person('阿飞', 22);
        console.log('实例对象', obj.__proto__);//没有方法 但可以调用
        //每一个实例对象都有一个属性:__proto__(隐形原型) ===Person.prototype
        // 非标准对象  w3c不认可
        // 作用:用于指向原型对象(prototype显式原型)
  • 构造函数封装
		 //构造函数
        function Person(uname, age) {
            this.uname = uname
            this.age = age
        }
        //原型对象
        Person.prototype.eatn = function () {
            console.log('吃饭');
        }
        //实例化对象
        let obj = new Person();
        console.log('实例化对象', obj);

在这里插入图片描述

1.2 继承

  • 继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。

1.2.1 原型继承

  • 基于构造函数原型对象实现面向对象的继承特性。
  // 中国人
  function Chinese() {
    this.skin = 'yellow';
    this.language = '中文';
  }
  // 日本人
  function Japanese() {
    this.skin = 'yellow';
    this.language = '日文';
  }
  
  // 人们【共有】的行为特征
  let people = {
    // 人的特征
    arms: 2,
    legs: 2,
    eyes:2,
    // 人的行为
    walk: function () {},
    sleep: function () {},
    sing: function () {}
  }
  
  // 第一步 prototype 重新赋值
  Chinese.prototype = people;
  // 第二步 指回构造函数
  Chinese.prototype.constructor = Chinese;
  • 防止继承时改变公共属性的值 使用公共构造函数的实例对象赋值给原型对象
		 function People() {
            this.head = 1
            this.eyes = 2
            this.leg = 2
            this.height = '100cm+'
            this.eat = function () {
                console.log('吃饭');
            }
        }
        //明星
        function Star() {
            this.daban = '打扮'
            this.money = '$$$'
        }
        //运动员
        function Player() {
            this.suzhi = '好'
            this.lihai = '天赋'
        }
        //继承 
        //1.公共构造函数的实例对象赋值给原型对象
        Star.prototype = new People
        //2.指会构造函数本身
        Star.prototype.constructor = Star
        let ak = new Star()
        console.log('ak', ak);

1.2,2 原型链

  • 原型链:由原型构成的链状结构
  • 作用:提供查找成员的机制
		//每一个对象都有__proto__
        function Person(uname, age) {
            this.uname = uname
            this.age = age
        }
        //原型对象
        Person.prototype.eat = function () {
            console.log('吃');
        }
        //实例化对象
        let obj = new Person('阿飞', 22);
        console.log(obj.__proto__);
        //原型对象也有__proto__
        console.log(Person.prototype.__proto__.constructor);
//原型链:由原型构成的链状结构
//作用:提供查找成员的机制
//就近原则

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Gik99

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

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

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

打赏作者

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

抵扣说明:

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

余额充值