美文网首页
理解对象、构造对象和抽象重复

理解对象、构造对象和抽象重复

作者: 饥人谷1904_陈俊锋 | 来源:发表于2019-08-21 21:21 被阅读0次

    JS中的对象

    一系列的无序的 key: value 的集合 (数组、函数、对象)

    获取对应值 对象.属性 / 对象[key]

    面向对象编程 OOP (Object-oriented programming)

    Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which may contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. A feature of objects is that an object's procedures can access and often modify the data fields of the object with which they are associated (objects have a notion of "this" or "self"). In OOP, computer programs are designed by making them out of objects that interact with one another. There is significant diversity of OOP languages, but the most popular ones are class-based, meaning that objects are instances of classes, which typically also determine their type. -- 来自 wiki

    面向对象编程是一个可能包含 以字段形式出现的数据(称为属性) 和 以程序形式出现的代码(称为方法) 的基于对象的概念的编程范式。对象的一个特征是对象的方法可以(从外部)访问对象的数据和修改对象的数据。在面向对象编程中,计算机程序的设计使他们在对象之外程序之间进行交互。面向对象语言是有显著多样性的,但大部分流行的是基于类的->对象是类的实例,通常也通过类确定其类型。


    一遍学编程一遍学英语
    paradigm: 范式
    concept: 概念
    in the form of fields: 以字段形式出现
    feaure: 特性
    procedures: 程序
    access: 访问 modify: 修改
    interact with ...: 与...交互
    significant diversity: 显著的多样性
    instances of: ...的实例


    面向过程的思路:一次性实现所有的流程

    面向对象的思路:把某个功能看成一个整体(对象),通过调用对象的某个方法来启动功能。用的时候不用考虑这个对象内部的实现细节,在去实现这个对象细节的时候不用管谁去调用。

    面向对象的好处:简洁可控容易维护

    构造对象

    一、抛开类,使用 字面量 来构造一个对象

    var person = {
        name: "Nicholas",
        age: 29,
        job: "Software Engineer",
    
        sayName: function() {
            console.log(this.name)
        }
    }
    

    这样做的问题:

    1. 麻烦,每次构建一个对象都是复制一遍代码
    2. 想要个性化,只能通过手工赋值->使用者必须了解对象的详细内容

    这两个问题也是不能抛开类的重要原因,也是类的重要作用

    二、使用函数做自动化

    function createObj(nick, age) {
        var obj = {
            nick: nick,
            age: age,
            printName: function() {
                console.log(this.nick)
            }
        }
        return obj
    }
    
    var newObj = createObj("kofe", 20)
    newObj.printName() // "kofe"
    

    通过创建一个函数来实现自动创建对象的过程,个性化通过参数实现,使用者不必关注细节,只需传入指定参数即可

    这样做的问题:
    方法解决了构造过于复杂、需要了解细节的问题,但是构造出来的都是 object ,没有识别度

    new

    new 运算符接受一个函数 F 及其参数:new F(arguments)

    function Person(name, age) {
        this.name = name
        this.age = age
        this.sayName = function() {
            console.log(this.name)
        }
    }
    var chen = new Person('kofe', 20)
    

    上面的代码,简单理解为:

    1. 执行new Person
    • 创建一个空对象 {},名字为 tmpObj
    • 执行 Person 函数 ,过程中对 this 操作就是对 tmpObj 进行操作
    • 函数执行完后返回刚创建的 tmpObj
    1. 把 tmpObj 赋值给 chen (指向同一个对象)

    深入理解为:

    1. 创建类的实例。把一个空的对象的 __ proto __ 属性设置为 F.prototype
    2. 初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例
    3. 返回实例

    instanceof

    操作符,可以判断对象是否为某个类型的实例

    chen instanceof Person // true
    chen instanceof Object // true
    

    构造函数解决了上面所有问题,同时为实例带来了类型,但可以注意到每个实例的printName方法在实际作用上是一样的,但是每个实例要重复一遍,大量对象存在的时候就浪费内存了

    构造函数

    • 任何函数使用 new 表达式就是构造函数
    • 每个函数都自动添加一个 prototype 属性,这是一个对象
    • 每个对象都有一个内部属性 __ proto __ (规范中没有指定这个名称,但是浏览器都这么实现)指向其类型的 prototype 属性,类的实例也是对象,其 __ proto __ 属性指向“类”的 prototype
    构造对象.png

    通过图示我们可以看出,实例可以通过 __ proto __ 访问到其类型的 prototype 属性,意味着类的 prototype 对象可以作为一个公共容器,供所有实例访问。

    抽象重复

    • 所有实例都会通过原型链引用到类型的 prototype
    • prototype 相当于特定类型所有实例都可以访问到的一个公共容器
    • 重复的东西可以移动到这个公共容器里放一份就OK

    (例如:默认参数可以放到 prototype 里)

    function Person(name, age) {
        this.name = name
        this.age = age
    }
    
    Person.prototype.sayName = function() {
        console.log(this.name)
    }
    
    var p1 = new Person()
    p1.sayName()
    
    抽象重复.png

    通过函数定义了类 Person ,类(函数)自动获得属性 prototype
    每个类的实例都会有一个内部属性 __proto__ ,指向类的 prototype 属性

    相关文章

      网友评论

          本文标题:理解对象、构造对象和抽象重复

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