• JavaScript中的对象究竟指的是什么呢?
  • 发布于 2个月前
  • 141 热度
    0 评论
前言

如果你接触过C++、Java这类编程语言的话,一定对其中的面向对象语言特性有比较深刻的认识。而当你接触过这些语言后,再接触JavaScript时,你可能会觉得JavaScript中有关对象总是有些奇怪。不知你是否考虑过这样一个问题,即当我们在JavaScript谈论对象时,这个对象究竟指的什么呢?


究竟什么是面向对象

我相信,不同人对于面向对象可能有着不同的看法。从笔者角度来看面向对象中所提及的对象其实可以理解为对现实世界的抽象。以现实世界的牛、羊来举例,当我们谈及牛、羊时你脑海中大概率会快速浮现出牛、羊的大体样貌,为什么我们脑海中会立即形成这样的画面呢?很简单,因为通过日常的学习、观察我们已经潜移默化的记住了牛、羊的显著特征,而这些其所具有的特征,在编程的世界中有另外一个名词——属性。进一步,牛、羊通常都具有基本活动能力,例如,牛会发哞的叫声,而羊则会发出咩的叫声,因此在计算机世界中,我们通常通过行为来刻画事物所独有的特点。


通过上述分析,不难发现,面向对象中的对象并不是凭空而来的一个名词,其切实的反映了我们对于这个世界的认识。简而言之,面向对象就是在程序中通过数据和行为来刻画现实世界的事物,并以对象为基本单位来刻画现实世界中各个实体的交互。


JavaScript 中的对象

经过之前对于面向对象的解释,相信你对于面向对象已经有了基本的认识。在像C++、Java这类语言中,通常会使用类的方式来描述对象,进而延伸出面向对象中封装、继承、多态的三大特性。


而在JavaScript创立之初,其在某种程度上模仿Java进行设计。比如,其内部也包含有new,this等关键字。但是其也保留了一些自己特色,其可通过原型来替代extends关键字,进而来实现面向对象中继承的特性。


其实熟悉JavaScript的读者一定知道,JavaScript中常用到的对象通常有如下三种:
Object(对象) :Object是JavaScript中其他对象的基础。这一点类似于Java中的Object。
Array(数组) :Array对象用于存储和操作有序的数据集合,它具有各种方法用于添加、删除和操作数组元素。
Function(函数) :函数被认为是可以用来调用执行的代码块。将函数视为对象一定程度上来爱看可以认为是JavaScript所特有的。更进一步,在JavaScript中函数可以作为一等公民在JavaScript中进行传递和存储。

此时,可能你会有这样的疑惑。那便是当在JavaScript 谈及的对象时,这个对象究竟在指什么。在此先来说笔者的一个结论,从笔者视角来看,我认为可以将JavaScript 中的对象理解为由一组由属性和值构成的集合。换言之,在JavaScript 中你可以将对象理解为多个key-value对构成的集合。


例如,在如下这段代码中,其构建了一个User对象,并动态指定了user有两个属性:name和age。同时,还指定了一个sayHello方法。
  const user = new Object();
  // 动态添加属性
  user.name = "YiHang";
  user.age = "18"
 // 动态添加方法
 user.sayHello = function() {
  console.log("sayHello");
};
// 堆代码 duidaima.com
// 调用方法
user.sayHello();

通过观察不难发现,你可以通过赋值操作来完善化你的user对象。这个赋值操作不单单仅有变量,更有函数。而这些东西所表现出来的形式其实有点像key-value的形式。至此,相信你大概率理解了笔者之前所说的JavaScript中对象的核心就是由一组组属性和值组成的集合。


当理解了上述这段话后,再结合之前我们对于面向对象的介绍。你会发现在 JavaScript 中,我们之前谈及的属性和行为其实都被抽象为属性。同时, JavaScript允许使用者在运行时动态的为对象添改、删除属性,这使得JavaScript 具有动态性这一特征。而c++、Java是完全不具有这样特点的,其通常以类为模板来构建对象,而类在运行期间是不允许动态修改的!


函数也是对象
在此我们再来谈一谈 JavaScript 中的函数。不同于C++,Java,在JavaScript 中函数也是一种特殊的对象,它同样可以拥有属性和值,而函数和普通对象的区别在于函数可以被调用。
我们先来看一段 JavaScript 代码:
function sayHello(){
 var test = 1
 }
 sayHello.msg = "Hello JavaScript"
console.log(sayHello.msg)
在这段代码中,我们定义了一个函数 sayHello方法。同时,在上述代码中,我们给 sayHello函数设置了msg的属性。当然,你也可以通过sayHello()的形式来调用方法。进一步,因为函数是一种特殊的对象,所以在JavaScript中,函数可以赋值给一个变量,也可以作为函数的参数,还可以作为函数的返回值。
怎么样,这样来理解函数可以复制给一个变量是不是有一种豁然开朗的感觉?以此为基础,我们再来看如下这段代码:
function out(){
     var num = 1
     function inner(){
         num++
         console.log(number)
     }
 return inner
 }
 var  inner = out()
 inner()
观察上段代码可以看到,我们在 out函数中定义了一个新的inner函数,并且inner函数引用了out函数中的变量 num,当调用 out 函数的时候,它会返回inner 函数。这种复杂的逻辑在JavaScript中称为闭包!

(注:闭包的有关知识后续可能会分析,敬请期待~)


总结
众所周知,在ES6中JavaScript开始引入的class语法,进而可以通过一种更简洁、更清晰地定义对象和构造函数的方式。这种方式也使得JavaScript在语法功能上更类似C++,Java。

ES6后的class语法
    // ES5构造函数
    function Person(name, age) {
      this.name = name;
      this.age = age;
    }

    Person.prototype.sayHello = function() {
      console.log('Hello, ' + this.name);
    };

    // ES6 class
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }

      sayHello() {
        console.log(`Hello, ${this.name}`);
      }
总之,在笔者看来,JavaScript中谈论的对象和C++,Java中谈论的对象有着很大的不同,JavaScript中谈论的对象其实更像是:一组组由属性和值构成的集合。当然可能我的理解也可能有些偏颇,欢迎在评论区理性讨论和交流指正。当然,如果觉得文章有帮助,不妨点赞+收藏,方便后期回顾总结。
用户评论