专栏首页前端进阶谈一谈javascript面向对象

谈一谈javascript面向对象

从今天起我们开始讨论javascript的面向对象

面向对象概念理解

面向对象语言有个标志=>它们都具有类的概念,通过类可以创建任意多个具有相同属性和方法的对象。 面向对象有三大特性

  1. 封装
  2. 继承
  3. 多态

但JS中对象与纯面向对象语言中的对象是不同的

JS中的对象: 无序属性的集合,其属性可以包含基本值、对象或者函数。

可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。

创建对象的基本方法

我们前面在讲原型链的时候说过,两种创建对象的方法

对象字面量(对象直接量)

这是最快的 一个?:

  const hero = {
    name:"欧阳锋",
    nickname:"西毒",
    doSth:function(){
      console.log('灵蛇杖法');
    }

⚠️创建对象的属性名并不强制使用引号包裹,除了以下几种情况

  • 属性名中包含空格
  • 属性名中包含连字符(中划线)
  • 属性名中包含保留字
const obj={
    "go home":"包含了空格",
    "go-home":"包含了连字符",
    "for":"这是保留字"
}

new 实例化一个对象

通过new运算符创建并实例化一个新对象,new后面是一个构造函数

const hero = new Object()
hero.name = "欧阳锋"
hero.nickname = "西毒"
hero.doSth = function () {
    console.log('灵蛇杖法');
}

两种创建方法是一样的 创建对象通过以上两种方式似乎足够了,但是当场景稍微复杂一点,问题就显现出来了 当我门创建很多结构相同的对象时,会产生大量的重复代码,为了解决这个问题,出现了一个解决方案

工厂模式

工厂模式抽象了创建具体对象的过程,因为javascript无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象 一个?:

function createHero(name,nickname,doSth) {
    const obj = new Object()
    obj.name=name
    obj.nickname=nickname
    obj.doSth = function () {
        console.log(doSth);
    }
    return obj
}
const hero1 = createHero("欧阳锋","西毒","灵蛇杖法")
const hero2 = createHero("黄药师","东邪","碧海潮生曲")
console.log(hero1)

看下输出:

hero1和hero2都直接继承自Object实例,工厂模式就是像工厂一样来创建对象,创建的每一个对象都是通过new Object()来创建的 后来,开发人员有发现了更好的模式

构造函数模式

我们之前讨论过,通过使用自定义构造函数来实例化对象

function Hero(name, nickname, doSth) {
    this.name = name
    this.nickname = nickname
    this.doSth = function () {
        console.log(doSth);
    }
}
const hero3 = new Hero("欧阳锋","西毒","灵蛇杖法")
const hero4 = new Hero("黄药师","东邪","碧海潮生曲")
console.log(hero3);

注意⚠️:创建自定义构造函数,函数名首字母大写,用来和非构造函数进行区分 我们继续看下输出:

hero3是通过Hero实例化出来的,所以hero3先继承自Hero 要创建Hero的新实例,必须使用new操作符,以这种方式调用构造函数实际上会经历以下四个步骤,

  1. 创建一个新对象
  2. 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
  3. 执行构造函数中的代码(为这个新对象添加属性)
  4. 返回新对象

hero3和hero4都是Hero的实例,同时也是Object的实例 instanceof用于判断一个变量是否某个对象的实例

console.log(hero3 instanceof Hero);//=>true
console.log(hero3 instanceof Object);//=>true
console.log(hero4 instanceof Hero);//=>true
console.log(hero4 instanceof Object);//=>true

属性和方法(公有&私有)

?的?中,我们将属性和方法绑定在了构造函数Hero中的this上,hero3和hero4都可以访问这些属性 绑定在this上的属性我们称之为公有属性 绑定在this上的方法我们称之为公有方法 也就是说通过构造函数Hero实例化出来的对象是可以方位公有属性和公有方法的 既然有公有属性和公有方法,就一定会有私有属性和私有方法 我们做一下调整

function Hero(name, nickname, doSth) {
    let test = "私有属性"
    function method(){console.log("私有方法");} 
    this.name = name
    this.nickname = nickname
    this.doSth = function () {
        console.log(doSth);
    }
}
const hero3 = new Hero("欧阳锋","西毒","灵蛇杖法")
const hero4 = new Hero("黄药师","东邪","碧海潮生曲")
console.log(hero3);

看下输出:

在hero3中是不存在构造函数的私有属性和私有方法的 如果我们这创建完构造函数后,追加一下属性和方法,会怎么样呢?试试看

    function Hero(name, nickname, doSth) {
      let test = "私有属性"
      function method(){console.log("私有方法");} 
      this.name = name
      this.nickname = nickname
      this.doSth = function () {
        console.log(doSth);
      }
    }
    Hero.localAttr="测试属性"
    Hero.localMethod=function(){
      console.log('测试方法');
    }
    Hero.prototype.proAttr="原型属性"
    Hero.prototype.proMethod=function(){
      console.log('原型方法');
    }
    const hero3 = new Hero("欧阳锋","西毒","灵蛇杖法")
    const hero4 = new Hero("黄药师","东邪","碧海潮生曲")
    console.log(hero3);
    console.log('localAttr测试属性:',hero3.localAttr);
    console.log("localMethod测试方法:",hero3.localMethod);
    console.log("proAttr原型属性:",hero3.proAttr);
    console.log("proMethod原型方法:",hero3.proMethod);

看输出:

创建完实例对象后, 通过.运算符添加的属性是类静态公有属性(实例化的对象无法访问) 通过.运算符添加的方法是类静态公有方法(实例化的对象无法访问) 通过原型链添加的属性是公有属性(实例化的对象可以访问) 通过原型链添加的方法是公有方法(实例化的对象可以访问)

今天就到这里,明天不见不散

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • javascript异步与promise

    我们说处理javascript异步最常用的方式就是通过回调函数,对于回调函数我们昨天对此做了介绍 简单快速, 我们一般使用嵌套回调或者链式回调,会产生以下问题

    陌上寒
  • 关于javascript的原型和原型链,看我就够了(三)

    原型对象有一个constructor属性,指向该原型对象对应的构造函数 foo 为什么有 constructor 属性?那是因为 foo 是 Foo 的实例。 ...

    陌上寒
  • 从今天起开启对正则表达式的学习

    从今天开始关于webpack的讨论就告一段落了,如果遇到webpack有重大更新,我会随时更新,请对我保持持续关注。 每次遇到与表单验证和校验的相关问题都会很难...

    陌上寒
  • 空间映射网络--Spatial Transformer Networks

    Spatial Transformer Networks 主要对目标在特征空间做不变性归一化 解决 角度、尺度等变形引入的影响 Code: http...

    用户1148525
  • 创业新机遇?信用需求推动美国替代评分市场崛起

    大数据文摘
  • 04. Web大前端时代之:HTML5+CSS3入门系列~表单剩余

    上一次《04. Web大前端时代之:HTML5+CSS3入门系列~Input新增类型》只讲了表单的一部分,今天把下面的继续讲下: 几张图收工: 二、input新...

    逸鹏
  • Java Stream 流的合并操作

    Java Stream Api[1] 提供了很多有用的 Api 让我们很方便将集合或者多个同类型的元素转换为流进行操作。今天我们来看看如何合并 Stream 流...

    码农小胖哥
  • C# 温故而知新:Stream篇(—)

    (我可不想这么理解,这必定让我抓狂,我理解的流是向自然界的河流那样清澈而又美丽,c#中的流也是一样,许多技术或者说核心技术都需要流的帮忙)

    小端
  • C# 温故而知新:Stream篇(—)

    C# 温故而知新:Stream篇(—) 什么是Stream? MSDN 中的解释太简洁了: 提供字节序列的一般视图 (我可不想这么理解,这必定让我抓狂,我理解的...

    小端
  • 学习SQL【4】-聚合与排序

    随着表中记录(数据行)的不断积累,存储数据逐渐增加,有时我们可能希望计算出这些数据的合计值或者平均值等,这个时候就需要使用SQL语句的汇总操作等方法。 一:对表...

    爱吃西瓜的番茄酱

扫码关注云+社区

领取腾讯云代金券