前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Prototypal Inheritance with Javascript-JavaScript中的原型继承(基础概念篇)

Prototypal Inheritance with Javascript-JavaScript中的原型继承(基础概念篇)

作者头像
lesM10
发布2019-08-26 16:57:53
4320
发布2019-08-26 16:57:53
举报
文章被收录于专栏:自译文章/自学记录

因为上篇文章Prototypal Inheritance没有对一些基本概念作出阐述,所以加入这篇文章作为补充。

Introduction简介

许多人有着传统的面向对象语言(如C++,Java)的背景,当他们使用JavaScript时,JavaScript中的一些区域往往会使他们感到困惑。因为JavaScript的工作方式不同于传统的面向对象语言。

在这篇文章中,我想阐述JavaScript的面向对象的实现,特别是JavaScript是如何实现继承的。

Background背景

这篇文章假设读者都是熟悉JavaScript的。虽然这里阐述的概念普遍适用于所有的‘原型语言(如js)’,但是本文的例子只使用JavaScript来解释。

大多数读者都熟悉传统的继承(如C++,Java,C#中的继承)。但是当他们尝试理解JavaScript中的继承(原型继承)时,传统的继承可能会造成一定程度的困扰。JavaScript不是唯一的使用原型继承的语言。其它的诸如Self, Lua, NewtonScript也都是原型继承。

在传统的面向对象语言中,你可以依据抽象概念创建各种。我们可以给这些添加属性和行为。这些在我们的代码中被初始化并执行各种各样的动作和任务。例如,你可以定义一个Order类,并给Order类添加一个行为。在你的应用中,当需要的时候,你会创建这些Order类的实例,并调用这些实例的行为。


Objects in JavaScript - JavaScript中的对象

Objects在JavaScript中是个重要的原始类型。JavaScript也是基于Objects构建起来的。但是传统的面向对象语言是基于classes构建的。因此,在JavaScript中 你可以像下面那样创建一个object的实例。

代码语言:javascript
复制
myObject = new Object();

你也可以使用下面的语法,创建同样的对象

代码语言:javascript
复制
var myObject = {};

该语法使用了object literal语法。在JavaScript中,一个object基本上是键值对的集合。像下面的例子一样:

代码语言:javascript
复制
myObject = {"Firstname": "Fred",  "LastName": "Smith" };

从这个object literal概念,可以看出:这是JSON格式的来源。JSON是JavaScript中的不携带方法的对象。

因为JavaScript也是一个函数语言(函数是一等公民), 那么你也可以像下面的例子那样,使用函数创建对象:

代码语言:javascript
复制
function myObject(){}
var myObject = new myObject();

在JavaScript中你可以使用这些方法创建对象,让我们接着讨论继承


Inheritance with JavaScript - JavaScript中的继承

到目前为止,一切都相当地直接。但是,这并不是JavaScript的工作方式。JavaScript是没有的,面向对象的语言。在JavaScript中没有的概念。虽然某些文本可能揭示了,JavaScript有能力实现类继承,但是事实上并不是这样。这不过是语法甜点,给了传统的面向对象开发者‘在JavaScript中他们能实现类继承的错觉’。最重要的是“在JavaScript中的所有的继承 都是使用原型继承实现的”。这是因为:

  • JavaScript是没有的(所有传统的面向对象语言都依赖这个基本概念)。
  • 所有的继承最终都是通过原型链来实现的。

在JavaScript中只是模拟了传统的继承。


What is prototypal inheritance? 什么是原型继承?

在JavaScript中,所有的对象都包含一个内部的object property,被称之为prototype

代码语言:javascript
复制
Object.prototype

current object是依据prototype object构建的(current object的原型是prototype object)。该prototype object也包含一个prototype object, 并且前者是在后者的基础上构建的。沿该链条(也叫原型链)一直向上走的话,最终我们可以找到root Object。此时,我们不能继续向前了,因为我们到达了原型链的顶端。

让我们以对象o开始。

代码语言:javascript
复制
var o;

我们的对象o包含一个叫做prototype(即prototype对象)的属性。对象o就是基于该prototype对象创建的。

代码语言:javascript
复制
var o = new Object()
console.log("typeof Object: " + typeof o); //outputs object
var p = o.prototype;
console.log("typeof o.prototype: " + typeof p); //outputs undefined 

我们可以反复做这个操作,直到我们到达原型链的顶端。

JavaScript中 继承的实现 是靠2个重要的概念:

  • 遍历原型链 - 如果JavaScript找不到指定的property/method,那么它会查找对象的原型。如果在原型中找不到,它会查找原型的原型。它会沿着原型链查找每个对象的原型,直到找到指定的property/method,或者 到达原型链的顶端。
  • 同一个prototype object 可以被不同的对象共享。不同的对象可以共享同一个prototype object,因此这些不同的对象 共享 同样的方法和属性。

How do you implement prototypal inheritance? 你是如何实现原型继承的?

既然我们了解了‘在JavaScript中继承是如何被实现的’这个潜在的概念,让我们看一个简单的例子。这里我们定义了一个对象Vehicle。接着我们又给对象Vehicle添加了一个属性(叫name)和一个方法(该方法返回name属性)。

代码语言:javascript
复制
//使用函数, 定义和实例化了一个对象`Vehicle`

function Vehicle() {}
var vehicle = new Vehicle();

//为对象`Vehicle`添加属性。我们既可以把它们作为实例的methods/properties添加进来,也可以把它们添加到Vehicle的prototype,以便所有的Vehicle都能继承到这些属性和方法

//添加一个`instance property`
function Vehicle(name) {
    // 在`类`的每个实例上,`Instance properties`都可以被设置。
    
    this.name = name;
}

//为原型添加属性,确保了所有的实例都共享该属性

Vehicle.prototype.Name = function() {
    console.log("My name is " + this.name);
};

var vehicle = new Vehicle('Vehicle');
vehicle.Name(); // My name is Vehicle

到目前为止,一切顺利。让我们通过创建一个Car class来扩展Vehicle object

代码语言:javascript
复制
function Car(name){
    Vehicle.call(this, name);
}

Car.prototype = new Vehicle();
var car = new Car("Car");
car.Name();

我们所做的是 把Vehicle object赋值给Car的prototype。这允许Car object从Vehicle继承所有的方法和属性。我们使用JavaScript中的方法call()来实现这个目的。Vehicle.call(this, name)所做的是 “允许我们在调用函数时,指定该函数的执行上下文”。因此,这就是我们为什么传递this的原因。我们知道“Car已经从Vehicle继承了所有的属性和方法”,因为 我们调用了 只在Vehicle object上定义的Name()方法。


Summary

这种继承方式 对于习惯了传统面向对象的开发者来说:可能是更难理解的。我也是花了一段时间才完全‘掌握究竟发生了什么’。如果你使用JavaScript的话,那么 了解JavaScript是如何实现继承的 就很重要了。

本文翻译自https://www.codeproject.com/Articles/1007871/Prototypal-Inheritance-with-Javascript

转载请注明出处

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.06.19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Introduction简介
  • Background背景
  • Objects in JavaScript - JavaScript中的对象
  • Inheritance with JavaScript - JavaScript中的继承
  • What is prototypal inheritance? 什么是原型继承?
  • How do you implement prototypal inheritance? 你是如何实现原型继承的?
  • Summary
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档