美文网首页
【JS一问】JavaScript 面向对象的理解和感悟

【JS一问】JavaScript 面向对象的理解和感悟

作者: 前端菜篮子 | 来源:发表于2019-08-15 19:15 被阅读0次

    提问者的话

    1. 什么是面向对象,面向对象有哪些特点,以及这些特点的解释。

    2. JavaScript 如何实现这些特点,比如封装、继承、多态。

      • 如果关于上述三点,你能够解释到有多少种实现方式、优缺点是什么。
      • 以及近几年流行的解决方案是什么。这就是加分
      • 比如对于继承吧。类式继承、构造函数继承、组合继承、原型继承、寄生组合继承等
      • 说出大概的实现思路和优缺点,再介绍下 extends 或者 mixin 的实现
      • 甚至你可以衍生到JavaScript 的模块化发展
      • 甚至到为什么现在 TS 如此流行。
      • 那么可以说到这一环节解答的就非常棒了。
    3. 回答完 JavaScript 的面向对象,是不是可以从此衍生下为什么需要面向对象。

    4. 以及当先对于软件设计的高内聚、低耦合的思考?

    5. 来个对此题一个提纲挈领的总结?

      重学前端:面向对象还是基于对象?


    JavaScript中的对象不合群

    1. JavaScript中有对象的概念,但没有类的概念,ES6中的class也只是一个语法糖
    2. JavaScript对象中可以自由添加(删除修改)属性
    3. 关于面向对象基于对象的争论
      • 这两个词都出现在JavaScript标准的各个版本中。
      • 基于对象的定义:“语言和宿主的基础设施由对象来提供,并且 JavaScript程序即是一系列互相通讯的对象集合”
      • 基于对象的定义并未弱化面向对象的意思,反而更加说明了对象对于语言的重要性

    什么是面向对象

    1. Object:一切皆对象
    2. 对象并不是计算机领域凭空造出来的概念,它是顺着人类思维模式产生的一种抽象
    3. 人的成长过程中先认识到对象,然后才有过程、值的概念【一个苹果(实例)可以吃——所有苹果(类)可以吃——3(值)个苹果和3个梨的关系】
    4. 所以面对对象编程是更接近人类思维的一种编程范式
    5. 最成功的流派使用的方式来描述对象,如JAVA
    6. JavaScript选择了较冷门的原型因为一些公司政治原因,JavaScript 推出之时受管理层之命被要求模仿 Java,JavaScript 创始人 Brendan Eich 在“原型运行时”的基础上引入了 new、this 等语言特性,使之“看起来更像 Java”
    7. ES6之前,很多人试图将JavaScript变得更像基于类的语言,进而产生了很多所谓的“框架”,比如 PrototypeJS、Dojo事实上,它们成为了某种 JavaScript 的古怪方言,甚至产生了一系列互不相容的社群,显然这样做的收益是远远小于损失的
    8. 从运行角度谈论对象:任何代码执行都必定绕不开运行时的对象模型【运行时类的概念都是被弱化的
    9. JavaScript面向对象编程:
      • 命名空间是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。 JavaScript中,命名空间只是另一个包含方法、属性、对象的对象
      • 注意:需要认识到重要的一点是:与其他面向对象编程语言不同的是,Javascript中的普通对象和命名空间在语言层面上没有区别。这点可能会让JavaScript初学者感到迷惑。
      • 创造的JavaScript命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。
      • JavaScript有包括在其核心的几个对象,例如,Math,Object,Array和String对象

    JavaScript对象的特征

    1. 对象具有唯一标识性:即使是完全相同的两个对象,也并非是同一个对象
    let o1 = {a: 1}
    let o2 = {a: 1}
    console.log(o1 == o2) //false
    
    1. 对象具有状态:同一对象可能处于不同的状态之下
    2. 对象具有行为:对象的状态可能因为它的行为而产生变迁
    a) 状态和行为在不同的语言中使用不同的术语来描述
    b) java中称为属性(状态)和方法(行为)
    c) javascript中将状态和行为统一抽象为“属性”
    d) javascript中函数是一种特殊的对象
    let age = 20
    let o  = {
        name: 'Lily',
        sayHi(){
            console.log('Hi')
        }
    }
    
    1. 除了上述3个基本特征外,JavaScript的独特之处:高度的动态性,运行时改变对象的状态和行为(属性)的能力
    2. JavaScript的属性比别的语言更复杂,它提供了数据属性和访问属性(getter/setterJavaScript对象的两类属性

    封装&多态

    image
    1. 在该案例中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。

    2. 有了封装来看多态

      • 先定义父类和多个子类


        image
      • 有个工厂,根据不同的类型来调用不同的子类


        image
    3. 看看下面两篇文章,他们算是面向对象编程中的封装吗?

      axios的封装

      模块化的发展 ≈ 封装方式的发展?

    4. vue组件的封装属于哪一类型的封装呢?


    继承方案(继承的本质是复制)

    原型对象相关知识点复习下

    image
    1. 原型链继:多个实例对引用类型的操作会被篡改


      image
    2. 构造函数继承


      image
    3. 原型链+构造函数


      image
      image
    4. 原型式&寄生式:这个就不具体看了,用Object.create()

      image
    5. 构造函数+寄生式:看下继承章节第一张图片“组合式继承”

    6. 混入方式继承多个对象:Object.assign

      image
    7. ES6classextends

      阮一峰ES6 Class的继承:包括extendsMixin

      image
      extends继承的核心代码如下,其实现和上述的构造函数+寄生式一样
    function _inherits(subType, superType) {
      
        // 创建对象,创建父类原型的一个副本
        // 增强对象,弥补因重写原型而失去的默认的constructor 属性
        // 指定对象,将新创建的对象赋值给子类的原型
        subType.prototype = Object.create(superType && superType.prototype, {
            constructor: {
                value: subType,
                enumerable: false,
                writable: true,
                configurable: true
            }
        });
        
        if (superType) {
            Object.setPrototypeOf 
                ? Object.setPrototypeOf(subType, superType) 
                : subType.__proto__ = superType;
        }
    }
    
    1. 你用到继承了吗?

    关于继承有人会问:虽然js的继承原理我知道,js代码我也一直在写,但是js的继承真的有用?写了这么久一直都没有用过,倒是看了下es6的继承感觉和java挺像,应该挺实用的,我知道自己水平不够,我想问一下js的继承一般用在哪呢?

    1. 来看下上面问题的简单答案:
      • 举个简单粗暴的?,页面上可以弹出来的元素有Modal/Tips/Alert/Confirm这么几种,其实这几种元素都可以抽象成是一个具有 show 和 hide 方法的元素,这个时候,我们就可以写个ModalCore 的对象,写好show 和 hide 方法。然后上面的几个元素对象,继承这个就好了。
      • 我觉得,需要不需要,主要是取决于平时的工作需要吧,如果开发一些库的代码我猜八成会需要的,但是如果只是平时写一下页面什么的,很少需要,没有那么的抽象必要
      • 根据二八原则,JavaScript 20% 的语法可以完成 80% 的功能,继承大概属于剩余的 80% 语法吧
      • 本人自己用ExtJs的时候倒是经常用extends;用VUE封装组件和原来ExtJS的extends挺像的;VUE封装是调用一个旧的组件封装成新的组件比较多,用继承的方法较少

    ...

    软件的高内聚、低耦合:面向对象设计的七大原则

    ...


    ...

    JavaScript设计模式:来自w3cshool

    ...


    TypeScript相关

    1. TypeScript学习
    2. 使用TypeScript两年后
    3. VUETypeScript 支持

    结语

    相对于「一个程序只是一些函数的集合,或简单的计算机指令列表。」的传统软件设计观念而言,面向对象编程可以看作是使用一系列对象相互协作的软件设计。 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。

    面向对象程序设计【允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器】的目的是在编程中促进更好的灵活性和可维护性,在大型软件工程中广为流行。凭借其对模块化的重视,面向对象的代码开发更简单,更容易理解,相比非模块化编程方法, 它能更直接地分析, 编码和理解复杂的情况和过程。

    相关文章

      网友评论

          本文标题:【JS一问】JavaScript 面向对象的理解和感悟

          本文链接:https://www.haomeiwen.com/subject/gfstsctx.html