ECMA-262 V7.0 中关于对象的概述

来源:互联网 发布:大数据的技术架构 编辑:程序博客网 时间:2024/06/04 19:01

ECMA-262 V7.0 中关于对象的概述

原文:http://www.ecma-international.org/ecma-262/7.0/#sec-objects

尽管ECMAScript包含了用于定义类的关键字,但ECMAScript并不像C++、SmallTalk和Java那样是从根本上基于类的。相应的,对象可以被通过多种方式创建包括:字面声明、构造函数(创建对象然后执行代码初始化对象的全部或部分属性)等。每个构造器都是一个含有叫做prototype的属性的函数。prototype用于实现原型继承和属性共享。对象通过在new表达式中使用构造函数被创建,例如:new Date(2009,11) 创建一个新的Date对象。调用构造函数而不使用new关键字的结果和构造函数本身有关。例如,Date()产生一个表示当前日期和时间的字符串而不是一个对象。

每一个被创建的对象有一个对其构造函数的prototype属性的隐式引用(叫做对象的原型)。此外,一个原型可能有一个对它原型的非null的隐式引用,并且持续下去。这被叫做原型链。当我们引用对象的一个属性时,会引用原型链中第一个拥有相同属性名字的对应属性。换句话说,首先检查当前对象是否有我们想要的属性;如果有则获取该属性的引用;如果没有则去这个对象的原型中查找,如此下去。
图1
图1
一般来说,在一个基于类的面向对象语言中,状态是由实例提供的,方法是由类提供的,继承仅仅对于结构和行为。在ECMAScript中,状态和方法是由对象提供的,结构、行为和状态都会被继承。

如果对象的原型共享了某一属性和它的值,那么这个对象不会直接包含这个属性。图1指出:

与大多数基于类的面向对象语言不同的是,属性可以通过赋值的方式被动态添加给对象。也就是说,构造函数不需要给被创建对象的所有属性命名或赋值。上图中,我们可以通过给原型CFp注册新值来为cf1、cf2、cf3、cf4和cf5共享属性。

尽管ECMAScript不是天生基于类的,但通过构造函数、原型对象和方法这种通用的模式来定义类似类的抽象概念通常是合适的。ECMAScript的内建对象自身遵守了这样一个类似类的模式。从ECMAScript 2015开始,ECMAScript包含了定义类的语法来让开发者通过和内置对象的类似类的抽象模式相一致的方式类定义对象。

我的看法:
1、ES并不直接支持类和它的概念但却提供了一个类似的概念: 先来看看ES与其他面向对象语言(C++,java,c#等)关于类概念的区别,有两点,如文中所说:1、其他面向对象语言中类的实例提供了状态(既属性),类提供了方法。我们对一个对象调用方法时是掉用类定义中的方法,将其运行上下文设置为当前对象。同一类的实例调用的是同一组方法(在概念上和实现上皆是如此)。也就是说实例(数据集)是分别存储的,方法存储在它的类定义里面。但在ES中对象(数据集)和方法都是存在实例中的。2、其他面向对象语言继承的是结构和行为,结构是指对象的内容如何解释,行为就是方法。一个类的实例在内存中具备一块完全的独立空间,这个空间中包含这个类及其所有祖先类的所有属性的存储空间。我们新建一个这个类的实例,他们互不干扰,从祖先类到子类所有数据属性都是独立的。在ES中不是这样,它继承的是状态、结构和方法。既数据、如何解释数据和方法。这意味着如果两个对象具有相同的原型对象,那么对原型对象的修改会同时影响到这两个对象。
所以我认为在ES中不存在类而仅仅存在对象,这不违背ES是面向对象的这一特点,面向对象不一定要有类。ES中继承的是对象而不是类,方法是属于对象的不是属于类的。ES中对象的继承是树形关系。在其他面向对象语言对象是独立的,类的继承是树形关系。
2、构造函数是对象的生成器而不是对象的类型:
文中指出构造函数用来初始化对象属性(也可以之后动态添加),构造函数的’prototype’会作为对象的原型。但不理解为对象的构造函数是它的类型,因为对象可以被动态修改属性,如果一个对象的构造函数是它的类型,当人们对它添加一个新的属性时它的类型是什么呢。

原创粉丝点击