ECMA-262中文翻譯 4.2.1 Object 物件

  Standard ECMA-262  5.1 Edition/June 2011

4.2.1 Objects
ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways

including via a literal notation or via constructors which create objects and then execute code that initialises all or part of them by assigning initial values to their properties. Each constructor is a function that has a property named "prototype" that is used to implement prototype-based inheritance and shared properties. Objects are created by using constructors in new expressions; for example, new Date(2009,11) creates a new Date object. Invoking a constructor without using new has consequences that depend on the constructor. For example, Date() produces a string representation of the current date and time rather than an object.

 

4.2.1 物件

ECMA腳本語言並不使用類別,這一點與C++,Smalltalk 或是Java等物件導向語言是不一樣的。雖然沒有類別的存在,ECMA腳本語言依然可以透過各種不同的方法來建立物件。其中包含了使用實字表示法(literal notation)或是藉由建構子(constructors )來建立物件,並且執行程式碼,這些程式碼可以用來初始化部分或者全部的物件屬性,初始化的方式是指定初始值給物件屬性。每個建構子都是一個函式,並且擁有一個名叫做"原型" (prototype)的屬性,原型可以用來實現"基於原型" (prototype-based )的繼承,和共享屬性。要用建構子來建立物件必須使用new 敘述;譬如說new Date(2009,11),建立了一個新的日期物件(Date)。調用一個建構子卻不使用new敘述那得到的結果會取決於建構子本身。譬如說Date()會傳回一個代表現在日期與時間的字串,而不是一個物件。

翻譯註解:

1. 實字表示法(literal notation)建立物件:

    fruit={name:"apple",price:15,color:"red"};

2. prototype-based inheritance  基於原型的繼承:

    可以想成是相對於 "基於類別的繼承" (class-based inheritance )的說法,接觸過物件導向語言的同好應該都知道,一般物件導向語言都是使用類別來完成繼承的,而ECMS262腳本語言卻是使用原型來完成繼承的功能,因此稱之為基於原型的繼承。

 

Every object created by a constructor has an implicit reference (called the object‘s prototype) to the value of its constructor‘s "prototype" property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.

每一個藉由建構子建立的物件都有一個隱性的參考(稱之為物件的原型)指到自身建構子的原型屬性的值。再進一步,原型也可能擁有一個非空的隱性參考到自身的原型,然後一直延續下去。這種關聯被稱之為原型鏈。當物件的屬性被參考到時,這個參考其實是指向原型鏈中第一個擁有同名屬性的物件中的屬性。換句話說,第一個直接被提及到的物件會先被檢查是否擁有同名的屬性,如果有同名的屬性,那這個參考就是指向這個物件的同名屬性;如過這物件不包含同名屬性,那會往原型鏈中下一個物件繼續檢查,一直下去。

翻譯註解:

1. 每一個藉由建構子建立的物件都有一個隱性的參考指到自身建構子的原型屬性的值:

   ( 1 )物件的原型其實就是物件的建構子的prototype屬性指向的物件。

   ( 2 ) 隱性的參考可以想成一個指向原型的變數,不過這變數無法直接被存取,所以才叫做隱性。

   ( 3 ) 在rhino中有個變數 __proto__可以指向原型,是個非標準的變數。

2. 原形鏈:

    每個物件都有自己的原型參考,可能是null,也可能指向一個物件,原型也有自己的原型參考。,一直串接下去就形成了原型鏈。

3.當物件的屬性被參考到時,這個參考其實是指向原型鏈中第一個擁有同名屬性的物件中的屬性:

   用下面圖來作例子: 

   alert ( cf1.q1 );

   會先找cf1中有沒有q1屬性,如果有就會傳回cf1中的q1屬性,如果cf1中沒有,那就會往cf1的原型,也就是CFp去找,一直找到原型鏈結束。

 

ecma262_prototype_chain

 

In a class-based object-oriented language, in general, state is carried by instances, methods are carried by classes, and inheritance is only of structure and behaviour. In ECMAScript, the state and methods are carried by objects, and structure, behaviour, and state are all inherited.

 

在基於類別的物件導向語言中,一般來說,狀態是屬於物件實例,而方法則是屬於類別,繼承只是單純的結構和行為。但是在ECMA腳本語言中,狀態和方法都是跟著物件走的...結構、行為、和狀態都會被繼承。

 

All objects that do not directly contain a particular property that their prototype contains share that property and its value. Figure 1 illustrates this:
CF is a constructor (and also an object). Five objects have been created by using new expressions: cf1, cf2, cf3, cf4, and cf5. Each of these objects contains properties named q1 and q2. The dashed lines represent the implicit prototype relationship; so, for example, cf3‘s prototype is CFp. The constructor, CF, has two properties itself, named P1 and P2, which are not visible to CFp, cf1, cf2, cf3, cf4, or cf5. The property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF), as are any properties found in CFp‘s implicit prototype chain that are not named q1, q2, or CFP1. Notice that there is no implicit prototype link between CF and CFp.
Unlike class-based object languages, properties can be added to objects dynamically by assigning values to them. That is, constructors are not required to name or assign values to all or any of the constructed object‘s properties. In the above diagram, one could add a new shared property for cf1, cf2, cf3, cf4, and cf5 by assigning a new value to the property in CFp.

 

對所有物件而言,物件本身不包含與原型同名的屬性,那就物件可以共享那不同名屬性和它的值。

圖一的解釋:

CF是一個建構子(也是一個物件),借由new敘建立了5個物件,分別是cf1,cf2,cf3,cf4,cf5,這5個物件中每個物件都包含了q1跟q2屬性,虛線代表著隱性的原型關係。所以說cf3的原型是CFp。建構子CF有2個私有的屬性P1跟P2,對於CFp, cf1, cf2, cf3, cf4, cf5而言 這兩個屬性都是不可見的。CFp中的CFP1是由cf1, cf2, cf3, cf4, cf5共享(不包含CF),同理,在CFp的隱性的原型鏈中,任何一個不叫做CFP1,q1,q2的屬性都是共享的。注意一點,CF跟CFp並不存在隱性的原型連結。

跟一般基於類別的物件導向語言不同的是,物件可以動態的新增屬性,新增的方法是指定值給屬性。所以說建構子並不需要命名或指定值給全部或任何建立物件的屬性。在上圖中,可以藉由指定值給CFp的屬性來新增 cf1, cf2, cf3, cf4, 和cf5 的共享屬性。

翻譯註解:

我在想上面的圖應該可以變成下面的程式,可以比較看看:

<script type="text/javascript">

function cfp(){}

var CFp=new cfp();
CFp.CFP1="CFP1 in CFp";

function CF(){
this.q1="q1 in CF";
this.q2="q2 in CF";
}

CF.prototype=CFp;
CF.P1="P1 in CF";
CF.P2="P2 in CF";

var cf1=new CF();
var cf2=new CF();
var cf3=new CF();
var cf4=new CF();
var cf5=new CF();

</script>

 

 

有寫錯請提醒一下,感激不盡。

參考資料: 

一個簡體中文的ECMA-262翻譯群組,雖然好像是舊版的,也沒全部翻完,不過可以參考看看。

ECMAScript 语言规范文档 ECMA-262 翻译工程

smiley如果你覺得寫的還不錯,請給我一個讚喔!!smiley

 
 

  按個讚!~支持本站!~

FB推薦載入中  

你可能會有興趣的文章:

回到頂部