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

2019-08-21  本文已影响0人  饥人谷1904_陈俊锋

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
  1. 把 tmpObj 赋值给 chen (指向同一个对象)

深入理解为:

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

instanceof

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

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

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

构造函数

构造对象.png

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

抽象重复

(例如:默认参数可以放到 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 属性

上一篇下一篇

猜你喜欢

热点阅读