深入理解JavaScript中的类型 - Go语言中文社区

深入理解JavaScript中的类型


记得大学java课的老师经常说:“万物皆对象”。

现实世界中,随处可见的一种事物就是对象,对象时事物存在的实体,如人类,书桌,计算机,等。人类解决问题的方式总是将负责的事物简单化,于是就会思考这些对象都是由哪些部分组成的。通常会将对象划分为两个部分,即静态部分与动态部分。 静态部分,就是不能动的部分,这部分被称为属性,任何对象都会具备其自身属性,如一个人,其属性包括高矮胖瘦,性别,年龄等。 动态部分,这部分被称为行为,如一个人可以哭泣,微笑,说话,行走。 人类通过探讨对象的属性和观察对象的行为以了解对象。

在计算机世界中,首先要将现实世界的实体抽象为对象,然后考虑这个对象具备的属性和行为

对象和类

支持面向对象编程(OOP)的语言通常以(主要语言有Java)或原型(主要语言有JavaScript)的形式出现,然后使用继承用于代码重用和可扩展性。那些使用类的时候有两个主要概念:

  • 类 –给定类型或对象类的数据格式定义和可用过程;也可能本身包含数据和过程(称为类方法),即类包含数据成员和成员函数
  • 对象 –类的实例

对象有时对应于现实世界中发现的事物。例如,一只大雁有 “翅膀”, “翅膀”, “脚”, “嘴”, 等属性。接着识别这只大雁的动态行为,如:“飞行”, “觅食”,  等。这些行为都是这个对象(大雁)基于其属性而具有的动作。 究其本质,所有的大雁都具有以上行为,可以将这些属性和行为封装起来以描述大雁这类动物,因此,类实质上就是封装对象属性和行为的载体,而对象则是类抽象出来的一个实例

每个对象都是特定类的实例(例如,名称字段设置为“ Mary”的对象可能是Employee类的实例)。面向对象编程中的过程称为方法。变量也称为字段,成员,属性或属性。这导致以下术语:

  • 类变量 –整体上属于类;每个只有一个副本
  • 实例变量或属性–属于单个对象的数据;每个对象都有自己的副本
  • 成员变量 –指的是由特定类定义的类变量和实例变量
  • 类方法–整体上属于类,并且只能访问类变量和过程调用中的输入
  • 实例方法–属于单个对象,并且可以访问被调用的特定对象的实例变量,输入和类变量

程序可以创建与运行相同类的许多实例,这些实例可以独立运行。对于在不同的数据集上使用相同的过程,这是一种简便的方法。 使用类的面向对象的编程有时称为基于类的编程,而基于原型的编程通常不使用类,但也可以使用相似的术语来定义对象和实例的概念。

基于类与基于原型

在基于类的语言中,预先定义了类,并根据这些类实例化了对象。如果从人类实例化了两个对象student和teacher,它们本质上都是人类,因此可以保证以相同的方式处理它们。

// java 代码 类的示例
class Person{
  //属性是成员变量,私有化属性,使得其他对象不能直接访问属性
  private String name;

  private int age;

  //参数及方法内定义的变量是局部变量
  public void setName(String name){
  	this.name = name;
  	}

  public String getName(){
  	return name;
  	}
}

// student teacher 是完全不同的两个实例
 Person student = new Person();

 Person teacher = new Person();

JavaScript也许是最著名的基于原型的编程语言,它从原型进行克隆而不是从类继承(与基于类的编程相反)来实现面向对象的概念。虽然自ES6以来出现了Class的语法糖,但Class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

ES6 的类,完全可以看作构造函数的另一种写法

class Point {
  // ...
}

typeof Point // "function"
Point === Point.prototype.constructor // true

// 上面代码表明,类的数据类型就是函数,类本身就指向构造函数。
复制代码

基于原型的语言中,对象是主要实体。甚至不存在任何类。对象的原型该对象链接到的另一个对象每个对象都有一个原型链接(只有一个)。可以基于已选择作为其原型的现有对象来创建新对象。如果存在对象水果,并且苹果和橙子都具有水果作为原型,则可以将两个不同的对象苹果和橙子称为水果。水果类的想法并不明确存在,但作为共享相同原型的对象的等价类。属性和方法的原型被委派至该原型中定义的等价类的所有对象。该对象单独拥有的属性和方法不能由相同等效类的其他对象共享;

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象包含特定类型的所有实例共享的属性和方法。

// JavaScript代码 类的示例

    function Person() { }
    Person.prototype.name = '张三';
    Person.prototype.age = 20;
    Person.prototype.job = '程序猿';
    Person.prototype.getName = function () {
        console.log(this.name)
    }
    Person.prototype.setName = function (name) {
        this.name = name;
    }

// person1和 person2 是可以共用的

    var person1 = new Person();
    person1.setName('李四');
    person1.getName();

    var person2 = new Person();
    person2.setName('王五');
    person2.getName();

    // 知道为什么返回true吗
    console.log(person1.getName() === person2.getName())

我们将getName,setName 直接添加到了Person的prototype属性中,构造函数变成了空函数。 Person.prototype对象的属性和方法是由所有实例共享,换句话说,person1和person2访问的都是同一组属性,和同一个getName,setName函数(这里就需要理解原型模式的工作原理了)。

总结

如何理解JavaScript中的面向对象:

面向对象语言有一个特点,它们都有类的概念,可以通过类创建任意多个具有相同属性和方法的对象,但是ECMAScript 是基于原型的编程语言  没有类的概念。因此它的对象与基于类的语言中的对象有所不同。ECMAScript中的对象是一组没有特定顺序的值,对象的每个属性或方法都有一个名字,而每个名字都映射到一个值(数据或函数) 如果在ECMAScript模拟类,可以通过 “原型模式” 实现

参考文档

  1. wikipedia-Object-oriented_programming
  2. 《java从入门到精通》
  3. 《JavaScript高级程序设计》
  4. es6.ruanyifeng.com

下面分享一份我整理的前端校招面试题,分了HTML、css、JavaScript、React、Vue、浏览器、服务端与网络、算法等等,共280页PDF。

《前端校招面试真题解析大全》

完整版面试题资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/hugo233/article/details/115580070
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-31 13:06:36
  • 阅读 ( 1279 )
  • 分类:Go深入理解

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢