mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
376 lines
29 KiB
HTML
376 lines
29 KiB
HTML
<article id="wikiArticle">
|
||
<div><a id="#%E5%AF%B9%E8%B1%A1%E5%92%8C%E5%B1%9E%E6%80%A7" name="#%E5%AF%B9%E8%B1%A1%E5%92%8C%E5%B1%9E%E6%80%A7"></a> <div class="prevnext" style="text-align: right;">
|
||
<p><a href="Guide/Text_formatting" style="float: left;">« 上一页</a><a href="Guide/Details_of_the_Object_Model">下一页 »</a></p>
|
||
</div></div>
|
||
<p class="summary"><span style="line-height: 1.5;">JavaScript </span>的设计是<span style="line-height: 1.5;">一个</span>简单的基于对象的范式。<span style="line-height: 1.5;">一个对象就是一系列属性的集合,一个属性包含一个名和一个值。一个属性的值可以是函数,这种情况下属性也被称为</span><em>方法</em><span style="line-height: 1.5;">。除了浏览器里面预定义的那些对象之外,你也可以定义你自己的对象。本章节讲述了怎么使用对象、属性、函数和方法,怎样实现自定义对象。</span></p>
|
||
<h2 id="对象概述">对象概述</h2>
|
||
<p><span style="line-height: 1.5;">javascript 中的对象(物体),和其它编程语言中的对象一样,可以比照现实生活中的对象(物体)来理解它。 javascript 中对象(物体)的概念可以比照着现实生活中实实在在的物体来理解。</span></p>
|
||
<p>在javascript中,一个对象可以是一个单独的拥有属性和类型的实体。我们拿它和一个杯子做下类比。一个杯子是一个对象(物体),拥有属性。杯子有颜色,图案,重量,由什么材质构成等等。同样,javascript对象也有属性来定义它的特征。</p>
|
||
<h2 id="对象和属性">对象和属性</h2>
|
||
<p><span style="line-height: 1.5;">一个 javascript 对象有很多属性。一个对象的属性可以被解释成一个附加到对象上的变量。对象的属性和普通的 javascript 变量基本没什么区别,仅仅是属性属于某个对象。属性定义了对象的特征(译注:动态语言面向对象的鸭子类型)。你可以通过点符号来访问一个对象的属性。</span></p>
|
||
<div style="margin-right: 270px;">
|
||
<pre class="brush: js">objectName.propertyName
|
||
</pre>
|
||
</div>
|
||
<p><span style="line-height: 1.5;">和其他 javascript 变量一样,对象的名字(可以是普通的变量)和属性的名字都是大小写敏感的。你可以在定义一个属性的时候就给它赋值。例如,我们创建一个myCar的对象然后给他三个属性,make,model,year。具体如下所示:</span></p>
|
||
<pre class="brush: js">var myCar = new Object();
|
||
myCar.make = "Ford";
|
||
myCar.model = "Mustang";
|
||
myCar.year = 1969; </pre>
|
||
<p>对象中未赋值的属性的值为<a href="Reference/Global_Objects/undefined" title="undefined是全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined的最初值就是原始数据类型undefined。"><code>undefined</code></a>(而不是<a href="Reference/Global_Objects/null" title="值 null 特指对象的值未设置。它是 JavaScript 基本类型 之一。"><code>null</code></a>)。</p>
|
||
<pre class="brush: js">myCar.noProperty; // undefined
|
||
</pre>
|
||
<p>JavaScript 对象的属性也可以通过方括号访问或者设置(更多信息查看 <a href="https://developer.mozilla.orgReference/Operators/Property_Accessors">property accessors</a>). 对象有时也被叫作关联数组, 因为每个属性都有一个用于访问它的字符串值。例如,你可以按如下方式访问 <code>myCar </code>对象的属性:</p>
|
||
<pre class="brush: js">myCar["make"] = "Ford";
|
||
myCar["model"] = "Mustang";
|
||
myCar["year"] = 1969;
|
||
</pre>
|
||
<p>一个对象的属性名可以是任何有效的 JavaScript 字符串,或者可以被转换为字符串的任何类型,包括空字符串。然而,一个属性的名称如果不是一个有效的 JavaScript 标识符(例如,一个由空格或连字符,或者以数字开头的属性名),就只能通过方括号标记访问。这个标记法在属性名称是动态判定(属性名只有到运行时才能判定)时非常有用。例如:</p>
|
||
<pre><code>// 同时创建四个变量,用逗号分隔
|
||
</code>var myObj = new Object(),
|
||
str = "myString",
|
||
rand = Math.random(),
|
||
obj = new Object();
|
||
|
||
myObj.type = "Dot syntax";
|
||
myObj["date created"] = "String with space";
|
||
myObj[str] = "String value";
|
||
myObj[rand] = "Random Number";
|
||
myObj[obj] = "Object";
|
||
myObj[""] = "Even an empty string";
|
||
|
||
console.log(myObj);
|
||
</pre>
|
||
<p><span id="result_box" lang="zh-CN"><span>请注意,方括号中的所有键都将转换为字符串类型,因为JavaScript中的对象只能使用String类型作为键类型。</span> <span>例如,在上面的代码中,当将键obj添加到myObj时,JavaScript将调用obj.toString()方法,并将此结果字符串用作新键。</span></span></p>
|
||
<p>你也可以通过存储在变量中的字符串来访问属性:</p>
|
||
<div style="width: auto;">
|
||
<pre class="brush: js">var propertyName = "make";
|
||
myCar[propertyName] = "Ford";
|
||
|
||
propertyName = "model";
|
||
myCar[propertyName] = "Mustang";
|
||
</pre>
|
||
</div>
|
||
<p><span style="line-height: 1.5;">你可以在 </span><span style="line-height: 1.5;"> </span><a class="internal" href="/zh-CN/docs/JavaScript/Guide/Statements#for...in_Statement" style="line-height: 1.5;" title="zh-CN/docs/JavaScript/Guide/Statements#for...in Statement">for...in</a><span style="line-height: 1.5;"> 语句中使用方括号标记以枚举一个对象的所有属性。为了展示它如何工作,下面的函数当你将对象及其名称作为参数传入时,显示对象的属性:</span></p>
|
||
<pre class="brush: js">function showProps(obj, objName) {
|
||
var result = "";
|
||
for (var i in obj) {
|
||
if (obj.hasOwnProperty(i)) {
|
||
result += objName + "." + i + " = " + obj[i] + "\n";
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
</pre>
|
||
<p>因而,对于函数调用 <code>showProps(myCar, "myCar")</code> 将返回以下值:</p>
|
||
<pre class="brush: js">myCar.make = Ford
|
||
myCar.model = Mustang
|
||
myCar.year = 1969
|
||
</pre>
|
||
<h2 id="枚举一个对象的所有属性">枚举一个对象的所有属性</h2>
|
||
<p>从 <a class="new" href="/zh-CN/docs/JavaScript/ECMAScript_5_support_in_Mozilla" rel="nofollow" title="zh-CN/docs/JavaScript/ECMAScript 5 support in Mozilla">ECMAScript 5</a> 开始,有三种原生的方法用于列出或枚举对象的属性:</p>
|
||
<ul>
|
||
<li><a href="/zh-CN/docs/JavaScript/Reference/Statements/for...in" title="zh-CN/docs/JavaScript/Reference/Statements/for...in">for...in</a> 循环<br/>
|
||
该方法依次访问一个对象及其原型链中所有可枚举的属性。</li>
|
||
<li><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/keys" title="zh-CN/docs/JavaScript/Reference/Global Objects/Object/keys">Object.keys(o)</a><br/>
|
||
该方法返回一个对象 <code>o</code> 自身包含(不包括原型中)的所有属性的名称的数组。</li>
|
||
<li><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames" title="zh-CN/docs/JavaScript/Reference/Global Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames(o)</a><br/>
|
||
该方法返回一个数组,它包含了对象 <code>o</code> 所有拥有的属性(无论是否可枚举)的名称。</li>
|
||
</ul>
|
||
<p>在 ECMAScript 5 之前,没有原生的方法枚举一个对象的所有属性。然而,可以通过以下函数完成:</p>
|
||
<pre class="brush: js">function listAllProperties(o){
|
||
var objectToInspect;
|
||
var result = [];
|
||
|
||
for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
|
||
result = result.concat(Object.getOwnPropertyNames(objectToInspect));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
</pre>
|
||
<p>这在展示 “隐藏”(在原型中的不能通过对象访问的属性,因为另一个同名的属性存在于原型链的早期)的属性时很有用。可以通过在数组中去除同名元素即可轻松地列出访问的属性。</p>
|
||
<h2 id="创建新对象">创建新对象</h2>
|
||
<p>JavaScript 拥有一系列预定义的对象。另外,你可以创建你自己的对象。从 JavaScript 1.2 之后,你可以通过对象初始化器(Object Initializer)创建对象。或者你可以创建一个构造函数并使用该函数和 <code>new</code> 操作符初始化对象。</p>
|
||
<h3 id="使用对象初始化器">使用对象初始化器</h3>
|
||
<p>除了通过构造函数创建对象之外,你也可以通过对象初始化器创建对象。使用对象初始化器也被称作通过字面值创建对象。对象初始化器与 C++ 术语相一致。</p>
|
||
<p>通过对象初始化器创建对象的语法如下:</p>
|
||
<pre class="brush: js">var obj = { property_1: value_1, // property_# 可以是一个标识符...
|
||
2: value_2, // 或一个数字...
|
||
<span lang="EN-US" style="">["property" +3]</span>:<span lang="EN-US" style=""> value_3</span>,<span lang="EN-US" style=""><span style=""> </span></span>// 或<span style="">一个可计算的<span lang="EN-US">key</span>名<span lang="EN-US">...</span></span>
|
||
// ...,
|
||
"property n": value_n }; // 或一个字符串
|
||
</pre>
|
||
<p> </p>
|
||
<p>这里 <code>obj</code> 是新对象的名称,每一个 <code>property_<em>i</em></code> 是一个标识符(可以是一个名称、数字或字符串字面量),并且每个 <code>value_<em>i</em></code> 是一个其值将被赋予 <span style="font-family: courier new,andale mono,monospace; line-height: 1.5;">property_</span><em>i </em><span style="line-height: 1.5;">的表达式。</span><code style="font-style: normal; line-height: 1.5;">obj</code><span style="line-height: 1.5;"> 与赋值是可选的;如果你不需要在其他地方引用对象,你就不需要将它赋给一个变量。(注意在接受一条语句的地方,你可能需要将对象字面量括在括号里,从而避免将字面量与块语句相混淆)</span></p>
|
||
<p>如果一个对象是通过在顶级脚本的对象初始化器创建的,则 JavaScript 在每次遇到包含该对象字面量的表达式时都会创建对象。同样的,在函数中的初始化器在每次函数调用时也会被创建。</p>
|
||
<p>下面的语句只有当 <code>cond</code> 表达式的值为 <code>true</code> 时创建对象并将其赋给变量 <code>x</code>。</p>
|
||
<pre class="brush: js">if (cond) var x = {hi: "there"};
|
||
</pre>
|
||
<p>下例创建了有三个属性的 <code>myHonda</code> 对象。注意它的 <code>engine</code> 属性也是一个拥有自己属性的对象。</p>
|
||
<pre class="brush: js">var myHonda = {color: "red", wheels: 4, engine: {cylinders: 4, size: 2.2}};
|
||
</pre>
|
||
<p>你也可以用对象初始化器来创建数组。参见 <a href="Values%2C_variables%2C_and_literals#Array_literals">array literals</a>.</p>
|
||
<p>在 JavaScript 1.1 及更早版本中,你不能使用对象初始化器。你只能通过使用构造函数或其他对象的函数来创建对象。参见 <a href="#使用构造函数">使用构造函数</a>.</p>
|
||
<h3 id="使用构造函数">使用构造函数</h3>
|
||
<p>作为另一种方式,你可以通过两步来创建对象:</p>
|
||
<ol>
|
||
<li>通过创建一个构造函数来定义对象的类型。首字母大写是非常普遍而且很恰当的惯用法。</li>
|
||
<li>通过 <code>new 创建对象实例。</code></li>
|
||
</ol>
|
||
<p>为了定义对象类型,为对象类型创建一个函数以声明类型的名称、属性和方法。例如,你想为汽车创建一个类型,并且将这类对象称为 <code>car</code> ,并且拥有属性 make, model, 和 year,你可以创建如下的函数:</p>
|
||
<pre class="brush: js">function Car(make, model, year) {
|
||
this.make = make;
|
||
this.model = model;
|
||
this.year = year;
|
||
}
|
||
</pre>
|
||
<p>注意通过使用 this 将传入函数的值赋给对象的属性。</p>
|
||
<p>现在你可以象这样创建一个 <code>mycar</code> 对象:</p>
|
||
<pre class="brush: js">var mycar = new Car("Eagle", "Talon TSi", 1993);
|
||
</pre>
|
||
<p>该创建了 <code>mycar</code> 并且将指定的值赋给它的属性。因而 <code>mycar.make</code> 的值是字符串 "Eagle", <code>mycar.year</code> 的值是整数 1993,依此类推。</p>
|
||
<p>你可以通过调用 <code>new</code> 创建任意数量的 <code>car </code>对象。例如:</p>
|
||
<pre class="brush: js">var kenscar = new Car("Nissan", "300ZX", 1992);
|
||
var vpgscar = new Car("Mazda", "Miata", 1990);
|
||
</pre>
|
||
<p>一个对象的属性值可以是另一个对象。例如,假设你按如下方式定义了 <code>person</code> 对象:</p>
|
||
<pre class="brush: js">function Person(name, age, sex) {
|
||
this.name = name;
|
||
this.age = age;
|
||
this.sex = sex;
|
||
}
|
||
</pre>
|
||
<p>然后按如下方式创建了两个 <code>person</code> 实例:</p>
|
||
<pre class="brush: js">var rand = new Person("Rand McKinnon", 33, "M");
|
||
var ken = new Person("Ken Jones", 39, "M");
|
||
</pre>
|
||
<p>那么,你可以重写 <code>car</code> 的定义以包含一个拥有它的 <code>owner</code> 属性,如:</p>
|
||
<pre class="brush: js">function Car(make, model, year, owner) {
|
||
this.make = make;
|
||
this.model = model;
|
||
this.year = year;
|
||
this.owner = owner;
|
||
}
|
||
</pre>
|
||
<p>你可以按如下方式创建新对象:</p>
|
||
<pre class="brush: js">var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
|
||
var car2 = new Car("Nissan", "300ZX", 1992, ken);
|
||
</pre>
|
||
<p>注意在创建新对象时,上面的语句将 <code>rand</code> 和 <code>ken</code> 作为 <code>owner</code> 的参数值,而不是传入字符串字面量或整数值。接下来你如果想找出 car2 的拥有者的姓名,你可以访问如下属性:</p>
|
||
<pre class="brush: js">car2.owner.name
|
||
</pre>
|
||
<p>注意你总是可以为之前定义的对象增加新的属性。例如,语句</p>
|
||
<pre class="brush: js">car1.color = "black";
|
||
</pre>
|
||
<p>为 <code>car1</code> 增加了 <code>color</code> 属性,并将其值设为 "black." 然而,这并不影响其他的对象。想要为某个类型的所有对象增加新属性,你必须将属性加入到 <code>car </code>对象类型的定义中。</p>
|
||
<h3 id="使用_Object.create_方法">使用 Object.create 方法</h3>
|
||
<p>对象也可以用 <a href="Reference/Global_Objects/Object/create" title="Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)"><code>Object.create()</code></a> 方法创建。该方法非常有用,因为它允许你为创建的对象选择其原型对象,而不用定义一个构造函数。</p>
|
||
<pre class="brush: js">// Animal properties and method encapsulation
|
||
var Animal = {
|
||
type: "Invertebrates", // Default value of properties
|
||
displayType : function() { // Method which will display type of Animal
|
||
console.log(this.type);
|
||
}
|
||
}
|
||
|
||
// Create new animal type called animal1
|
||
var animal1 = Object.create(Animal);
|
||
animal1.displayType(); // Output:Invertebrates
|
||
|
||
// Create new animal type called Fishes
|
||
var fish = Object.create(Animal);
|
||
fish.type = "Fishes";
|
||
fish.displayType(); // Output:Fishes
|
||
</pre>
|
||
<p>该函数更多的信息及详细用法,参见 <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/create">Object.create method</a></p>
|
||
<h3 id="继承"><strong>继承</strong></h3>
|
||
<p>所有的 JavaScript 对象继承于至少一个对象。被继承的对象被称作原型,并且继承的属性可通过构造函数的 <code>prototype</code> 对象找到。查看更多详细 <a href="https://developer.mozilla.orgInheritance_and_the_prototype_chain">Inheritance and the prototype chain</a></p>
|
||
<h3 id="对象属性索引"><strong>对象属性索引</strong></h3>
|
||
<p>在 JavaScript 1.0 中,你可以通过名称或序号访问一个属性。但是在 JavaScript 1.1 及之后版本中,如果你最初使用名称定义了一个属性,则你必须通过名称来访问它;而如果你最初使用序号来定义一个属性,则你必须通过索引来访问它。</p>
|
||
<p>这个限制发生在你通过构造函数创建一个对象和它的属性(就象我们之前通过 <code>Car</code> 对象类型所做的那样)并且显式地定义了单独的属性(如 <code>m</code><span style="font-family: courier new,andale mono,monospace; line-height: 1.5;">yCar.color = "red")</span><span style="line-height: 1.5;">之时。如果你最初使用索引定义了一个对象属性,例如 <code>myCar[5] = "25"</code>,则你只可能通过 <code>myCar[5]</code> 引用它。</span></p>
|
||
<p><span style="line-height: 1.5;">这条规则的例外是从与HTML对应的对象,例如 <code>forms</code> 数组。对于这些数组的元素,你总是既可以通过其序号(依据其在文档中出现的顺序),也可以按照其名称(如果有的话)访问它。举例而言,如果文档中的第二个 <code><form></code> 标签有一个 <code>NAME</code> 属性且值为<code> "myForm",访问该 form 的方式可以是 document.forms[1],document.forms["myForm"]或 document.myForm。</code></span></p>
|
||
<p><span style="font-size: 1.7142857142857142rem; letter-spacing: -0.5px; line-height: 24px;">为对象类型定义属性</span></p>
|
||
<p>你可以通过 <code>prototype </code>属性为之前定义的对象类型增加属性。这为该类型的所有对象,而不是仅仅一个对象增加了一个属性。下面的代码为所有类型为 <code>car </code>的对象增加了 <code>color</code> 属性,然后为对象 <code>car1</code> 的 <code>color</code> 属性赋值:</p>
|
||
<pre class="brush: js">Car.prototype.color = null;
|
||
car1.color = "black";
|
||
</pre>
|
||
<p>参见<span style="line-height: 1.5;"> </span><a href="/zh-CN/docs/JavaScript/Reference" style="line-height: 1.5; text-decoration: underline;" title="zh-CN/docs/JavaScript/Reference">JavaScript Reference</a><span style="line-height: 1.5;"> 中</span><span style="line-height: 1.5;"> Function 对象的 </span><a class="new" href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Function/prototype" rel="nofollow" style="line-height: 1.5;" title="zh-CN/docs/JavaScript/Reference/Global Objects/Function/prototype"><code>prototype</code> 属性</a><span style="line-height: 1.5;"> 。</span></p>
|
||
<h3 id="定义方法">定义方法</h3>
|
||
<p>一个<em>方法</em> 是关联到某个对象的函数,或者简单地说,一个方法是一个值为某个函数的对象属性。定义方法就像定义普通的函数,除了它们必须被赋给对象的某个属性。查看 <a href="https://developer.mozilla.orgReference/Functions/Method_definitions">method definitions</a>了解更多详情例如:</p>
|
||
<pre class="brush: js">objectName.methodname = function_name;
|
||
|
||
var myObj = {
|
||
myMethod: function(params) {
|
||
// ...do something
|
||
}
|
||
|
||
// 或者 这样写也可以
|
||
|
||
myOtherMethod(params) {
|
||
// ...do something else
|
||
}
|
||
};
|
||
</pre>
|
||
<p>这里 <code>objectName</code> 是一个已经存在的对象,<code>methodname</code> 是方法的名称,而 <code style="font-style: normal; line-height: 1.5;">function_name</code><span style="line-height: 1.5;"> </span><span style="line-height: 1.5;">是函数的名称。</span></p>
|
||
<p>你可以在对象的上下文中象这样调用方法:</p>
|
||
<pre class="brush: js">object.methodname(params);
|
||
</pre>
|
||
<p>你可以在对象的构造函数中包含方法定义来<span style="line-height: 1.5;">为某个对象类型定义方法。例如,你可以为之前定义的 <code>car</code> 对象定义一个函数格式化并显示其属性:</span></p>
|
||
<pre class="brush: js">function displayCar() {
|
||
var result = "A Beautiful " + this.year + " " + this.make
|
||
+ " " + this.model;
|
||
pretty_print(result);
|
||
}
|
||
</pre>
|
||
<p>这里 <code>pretty_print</code> 是一个显示横线和一个字符串的函数。注意使用 this 指代方法所属的对象。</p>
|
||
<p>你可以在对象定义中通过增加下述语句将这个函数变成 <code>Car</code> 的方法:</p>
|
||
<pre class="brush: js">this.displayCar = displayCar;
|
||
</pre>
|
||
<p>因此,<code>Car</code> 的完整定义看上去将是:</p>
|
||
<pre class="brush: js">function Car(make, model, year, owner) {
|
||
this.make = make;
|
||
this.model = model;
|
||
this.year = year;
|
||
this.owner = owner;
|
||
this.displayCar = displayCar;
|
||
}
|
||
</pre>
|
||
<p>然后你可以按如下方式为每个对象调用 <code>displayCar</code> 方法:</p>
|
||
<pre class="brush: js">car1.displayCar();
|
||
car2.displayCar();
|
||
</pre>
|
||
<p> </p>
|
||
<h3 id="通过_this_引用对象">通过 <code>this</code> 引用对象</h3>
|
||
<p> </p>
|
||
<p>JavaScript 有一个特殊的关键字 <code>this</code>,它可以在方法中使用以指代当前对象。例如,假设你有一个名为 <code>validate</code> 的函数,它根据给出的最大与最小值检查某个对象的 <code>value</code> 属性:</p>
|
||
<pre class="brush: js">function validate(obj, lowval, hival) {
|
||
if ((obj.value < lowval) || (obj.value > hival)) {
|
||
alert("Invalid Value!");
|
||
}
|
||
}
|
||
</pre>
|
||
<p>然后,你可以在每个元素的 <code>onchange</code> 事件处理器中调用 <code>validate</code>,并通过 <code>this</code> 传入相应元素,代码如下:</p>
|
||
<pre class="brush: html"><input type="text" name="age" size="3"
|
||
onChange="validate(this, 18, 99)">
|
||
</pre>
|
||
<p>总的说来, <code>this</code> 在一个方法中指调用的对象。</p>
|
||
<p>当与 <code>form</code> 属性一起使用时,<code>this </code>可以指代当前对象的父窗体。在下面的例子中,窗体 <code>myForm</code> 包含一个 <code>Text </code>对象和一个按钮,当用户点击按键,<code>Text</code> 对象的值被设为窗体的名称。按钮的 <code>onclick</code> 事件处理器使用 <code>this.form</code> 以指代其父窗体,即 <code>myForm</code>。</p>
|
||
<pre class="brush: html"><form name="myForm">
|
||
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
|
||
<p><input name="button1" type="button" value="Show Form Name"
|
||
onclick="this.form.text1.value = this.form.name">
|
||
</p>
|
||
</form></pre>
|
||
<h3 id="定义_getters_与_setters"><strong>定义 getters 与 setters</strong></h3>
|
||
<p>一个 <a href="https://developer.mozilla.orgReference/Functions/get">getter</a> 是一个获取某个特定属性的值的方法。一个 <a href="https://developer.mozilla.orgReference/Functions/set">setter</a> 是一个设定某个属性的值的方法。你可以为预定义的或用户定义的对象定义 getter 和 setter 以支持新增的属性。定义 getter 和 setter 的语法采用对象字面量语法。</p>
|
||
<p>下面例子描述了getters 和 setters 是如何为用户定义的对象<code> o</code> 工作的。</p>
|
||
<pre class="brush: js">var o = {
|
||
a: 7,
|
||
get b() {
|
||
return this.a + 1;
|
||
},
|
||
set c(x) {
|
||
this.a = x / 2
|
||
}
|
||
};
|
||
|
||
console.log(o.a); // 7
|
||
console.log(o.b); // 8
|
||
o.c = 50;
|
||
console.log(o.a); // 25</pre>
|
||
<p><code>o</code> 对象的属性如下:</p>
|
||
<ul>
|
||
<li><code>o.a</code> — 数字</li>
|
||
<li><code>o.b</code> — 返回 <code>o.a</code> + 1 的 getter</li>
|
||
<li><code>o.c</code> — 由 <code>o.c 的值所设置 <code>o.a</code> 值的</code> setter</li>
|
||
</ul>
|
||
<p>请注意在一个对象字面量语法中定义getter和setter使用"[gs]et property()"的方式(相比较于__define[GS]etter__)时,并不是获取和设置某个属性自身,容易让人误以为是"[gs]et propertyName(){ }"这样错误的使用方法。定义一个getter或setter函数使用语法"[gs]et property()",定义一个已经声明的函数作为的getter和setter方法,使用<code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/defineProperty" title="zh-CN/docs/Core JavaScript 1.5 Reference/Global
|
||
Objects/Object/defineProperty">Object.defineProperty</a></code>(或者 <code><a class="new" href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/defineGetter" rel="nofollow" title="zh-CN/docs/Core JavaScript 1.5 Reference/Global
|
||
Objects/Object/defineGetter">Object.prototype.__defineGetter__</a></code> 旧语法回退)</p>
|
||
<p>下面这个例子展示使用getter和setter方法扩展 <a href="Reference/Date" title="此页面仍未被本地化, 期待您的翻译!"><code>Date</code></a>原型,为预定义好的Date类添加一个year的属性。定义属性year的getter和setter方法用到了Date类中已存在的getFullYear和setFullYear方法。</p>
|
||
<p>定义属性year的getter和setter:</p>
|
||
<pre class="brush: js">var d = Date.prototype;
|
||
Object.defineProperty(d, "year", {
|
||
get: function() { return this.getFullYear() },
|
||
set: function(y) { this.setFullYear(y) }
|
||
});
|
||
</pre>
|
||
<p>通过一个Date对象使用getter和setter:</p>
|
||
<pre class="brush: js">var now = new Date();
|
||
console.log(now.year); // 2000
|
||
now.year = 2001; // 987617605170
|
||
console.log(now);
|
||
// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
|
||
</pre>
|
||
<p>原则上,getter 和 setter 既可以:</p>
|
||
<ul>
|
||
<li>使用 <a href="#使用对象初始化器">使用对象初始化器</a> 定义</li>
|
||
<li>也可以之后随时使用 getter 和 setter 添加方法添加到任何对象</li>
|
||
</ul>
|
||
<p>当使用 <a href="#使用对象初始化器">使用对象初始化器</a> 的方式定义getter和setter时,只需要在getter方法前加get,在setter方法前加set,当然,getter方法必须是无参数的,setter方法只接受一个参数(设置为新值),例如:</p>
|
||
<pre class="brush: js">var o = {
|
||
a: 7,
|
||
<strong>get</strong> b() { return this.a + 1; },
|
||
<strong>set</strong> c(x) { this.a = x / 2; }
|
||
};
|
||
</pre>
|
||
<p>使用Object.defineProperties的方法,同样也可以对一个已创建的对象在任何时候为其添加getter或setter方法。这个方法的第一个参数是你想定义getter或setter方法的对象,第二个参数是一个对象,这个对象的属性名用作getter或setter的名字,属性名对应的属性值用作定义getter或setter方法的函数,下面是一个例子定义了和前面例子一样的getter和setter方法:</p>
|
||
<pre class="brush: js">var o = { a:0 }
|
||
|
||
Object.defineProperties(o, {
|
||
"b": { get: function () { return this.a + 1; } },
|
||
"c": { set: function (x) { this.a = x / 2; } }
|
||
});
|
||
|
||
o.c = 10 // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
|
||
console.log(o.b) // Runs the getter, which yields a + 1 or 6
|
||
</pre>
|
||
<p>这两种定义方式的选择取决于你的编程风格和手头的工作量。当你定义一个原型准备进行初始化时,可以选择第一种方式,这种方式更简洁和自然。但是,当你需要添加getter和setter方法 —— 因为并没有编写原型或者特定的对象 ——使用第二种方式更好。第二种方式可能更能表现JavaScript语法的动态特性——但也会使代码变得难以阅读和理解。</p>
|
||
<h3 id="删除属性">删除属性</h3>
|
||
<p>你可以用 <a href="https://developer.mozilla.orgReference/Operators/delete">delete</a> 操作符删除一个<strong style="color: red;">不是继承而来</strong>的属性。下面的例子说明如何删除一个属性:</p>
|
||
<pre class="brush: js">//Creates a new object, myobj, with two properties, a and b.
|
||
var myobj = new Object;
|
||
myobj.a = 5;
|
||
myobj.b = 12;
|
||
|
||
//Removes the a property, leaving myobj with only the b property.
|
||
delete myobj.a;
|
||
</pre>
|
||
<p>如果一个全局变量不是用 <code>var</code> 关键字声明的话,你也可以用 <code>delete</code> 删除它:</p>
|
||
<pre class="brush: js">g = 17;
|
||
delete g;
|
||
</pre>
|
||
<p>参见<code><a href="Expressions_and_operators#delete">delete</a></code> 以获取更多信息。</p>
|
||
<h3 id="比较对象">比较对象</h3>
|
||
<p>在 JavaScript 中 objects 是一种引用类型。两个独立声明的对象永远也不会相等,即使他们有相同的属性,只有在比较一个对象和这个对象的引用时,才会返回true.</p>
|
||
<pre class="brush: js">// 两个变量, 两个具有同样的属性、但不相同的对象
|
||
var fruit = {name: "apple"};
|
||
var fruitbear = {name: "apple"};
|
||
|
||
fruit == fruitbear // return false
|
||
fruit === fruitbear // return false
|
||
</pre>
|
||
<div class="note">
|
||
<p><strong>注意:</strong> "===" 运算符用来检查数值是否相等: 1 === "1" // return false and 1 == "1" // return true</p>
|
||
</div>
|
||
<pre class="brush: js">// 两个变量, 同一个对象
|
||
var fruit = {name: "apple"};
|
||
var fruitbear = fruit; // 将fruit的对象<strong>引用</strong>(reference)赋值给 fruitbear
|
||
// 也称为将fruitbear“<em><strong>指向</strong></em>”fruit对象
|
||
// fruit与fruitbear都指向同样的对象
|
||
fruit == fruitbear // return true
|
||
fruit === fruitbear // return true</pre>
|
||
<p><font face="Consolas, Liberation Mono, Courier, monospace">了解更多关于比较操作符的用法,查看</font> <a href="https://developer.mozilla.orgReference/Operators/Comparison_Operators">Comparison operators</a>.</p>
|
||
<h2 id="sect1"> </h2>
|
||
<h2 id="附加参考">附加参考</h2>
|
||
<ul>
|
||
<li>想要深入了解,请阅读<a href="https://developer.mozilla.orgGuide/Details_of_the_Object_Model">details of javaScript's objects model</a>。</li>
|
||
<li>想要学习 ECMAScript 2015中类(一种创建对象的新方式),请阅读 <a href="https://developer.mozilla.orgReference/Classes">JavaScript classes</a> 章节。</li>
|
||
</ul>
|
||
<p> </p>
|
||
<p></p><div class="prevnext" style="text-align: right;">
|
||
<p><a href="Guide/Regular_Expressions" style="float: left;">« 上一页</a><a href="Guide/Details_of_the_Object_Model">下一页 »</a></p>
|
||
</div><p></p>
|
||
<div> </div>
|
||
</article> |