複雑なオブジェクトは、許可されているあらゆる JavaScript 値を保持できます。次のコードでは、myObject
という名前の Object()
オブジェクトを作成し、JavaScript で使用できるほとんどの値を表すプロパティを追加します。
例:sample29.html
リーリーここで学ぶべき簡単な概念は、複雑なオブジェクトには JavaScript で名目上表現できるものはすべて含めることができるということです。すべてのネイティブ オブジェクトは変更できるため、これが行われたのを見て驚かないでください。これは、オブジェクト形式の String()
、Number()
、および Boolean()
の値、つまり new## を使用して作成された値にも適用されます。 # 演算子を使用する場合。
Object()、
Array()、および
Function() オブジェクトには、他の複雑なオブジェクトを含めることができます。以下の例では、
Object() オブジェクトを使用してオブジェクト ツリーを設定することでこれを示します。
リーリー
同じ操作は、Array() オブジェクト (別名多次元配列) または
Function() オブジェクトを使用して実行できます。
リーリー
ここで理解すべき主な概念は、一部の複雑なオブジェクトは、プログラム的に有益な方法で他のオブジェクトをカプセル化するように設計されているということです。
以下の例では、ドット表記法を示しています。これは、オブジェクト名の後にピリオドを付け、その後に取得、設定、または更新するプロパティを続けて使用します (例:
objectName.財産### )。
例:sample32.html
リーリー
ドット表記は、オブジェクトのプロパティを取得、設定、または更新するための最も一般的な表記です。
角括弧表記は、必要な場合を除き、一般的には使用されません。次の例では、前の例で使用されていたドット表記を括弧表記に置き換えました。オブジェクト名の後には、開始括弧、プロパティ名 (引用符で囲んだ)、そして終了括弧が続きます:
例:sample33.html
リーリーブラケット表記は、プロパティ キーにアクセスする必要があり、プロパティ名を表す文字列値を含む変数を使用する必要がある場合に便利です。次の例では、角かっこ表記を使用してプロパティ
foobar にアクセスすることにより、ドット表記よりもかっこ表記の利点を示します。これを行うには、連結すると foobarObject
に含まれるプロパティ キーの文字列バージョンを生成する 2 つの変数を使用します。
例:sample34.html
さらに、括弧表記を使用すると、無効な JavaScript 識別子のプロパティ名を簡単に取得できます。以下のコードでは、プロパティ名 (文字列として有効) として数値と予約キーワードを使用しています。プロパティ名には角かっこ表記を使用してのみアクセスできます。
例:sample35.html
リーリーオブジェクトには他のオブジェクトを含めることができるため、
cody.object.object.object.object または cody['object']['object']['object']['object' ]
は以下の場所でご覧いただけます。これはオブジェクトチェーンと呼ばれます。オブジェクトのカプセル化は無期限に継続できます。
JavaScript ではオブジェクトは変更可能です。つまり、ほとんどのオブジェクトでいつでも取得、設定、更新を実行できます。括弧表記 (
など) を使用すると、他の言語の連想配列を模倣できます。
オブジェクト内のプロパティがメソッドの場合、必要なのは、
演算子 (例: cody.getGender()
) を使用してプロパティ メソッドを呼び出すことだけです。
演算子を使用すると、オブジェクトのプロパティを完全に削除できます。次のコード スニペットでは、foo
オブジェクトから bar
プロパティを削除します。
例:sample36.html
プロトタイプ チェーン上で見つかったプロパティは削除されません。
削除は、オブジェクトからプロパティを実際に削除する唯一の方法です。プロパティを
または null
に設定すると、そのプロパティの値のみが変更されます。オブジェクトからプロパティは削除されません。
という名前のプロパティにアクセスしようとしています。 myArray.foo
は myArray
オブジェクトのプロパティではないため、JavaScript はすぐに unknown
を返すと思うかもしれません。しかし、JavaScript は他の 2 つの場所 (Array.prototype
と Object.prototype
) で foo
の値を検索し、unknown
を返します。
例:sample37.html
<!DOCTYPE html><html lang="en"><body><script> var myArray = []; console.log(myArray.foo); // Logs undefined. /* JS will look at Array.prototype for Array.prototype.foo, but it is not there. Then it will look for it at Object.prototype, but it is not there either, so undefined is returned! */ </script></body></html>
财产。如果它有该属性,它将返回该属性的值,并且不会发生继承,因为原型链没有被杠杆化。如果实例没有该属性,JavaScript 将在对象的构造函数 prototype
对象中查找它。
所有对象实例都有一个属性,该属性是创建该实例的构造函数的秘密链接(又名 __proto__
)。可以利用这个秘密链接来获取构造函数,特别是实例构造函数的原型属性。
这是 JavaScript 中对象最令人困惑的方面之一。但让我们来推理一下。请记住,函数也是具有属性的对象。允许对象从其他对象继承属性是有意义的。就像说:“嘿,对象 B,我希望你分享对象 A 拥有的所有属性。”默认情况下,JavaScript 通过 prototype
对象将这一切连接到本机对象。当您创建自己的构造函数时,您也可以利用原型链。
JavaScript 到底是如何实现这一点的?在您了解它的本质之前,您会感到困惑:只是一组规则。让我们创建一个数组来更仔细地检查 prototype
属性。
示例:sample38.html
<!DOCTYPE html><html lang="en"><body><script> // myArray is an Array object. var myArray = ['foo', 'bar']; console.log(myArray.join()); // join() is actually defined at Array.prototype.join </script></body></html>
我们的 Array()
实例是一个具有属性和方法的对象。当我们访问其中一种数组方法时,例如 join()
,我们问自己:从 Array()
构造函数创建的 myArray 实例是否有自己的 join()
方法?我们来检查一下。
示例:sample39.html
<!DOCTYPE html><html lang="en"><body><script> var myArray = ['foo', 'bar']; console.log(myArray.hasOwnProperty('join')); // Logs false. </script></body></html>
不,没有。然而 myArray 可以访问 join()
方法,就好像它是它自己的属性一样。这里发生了什么?好吧,您刚刚观察了原型链的运行情况。我们访问了一个属性,尽管该属性不包含在 myArray 对象中,但 JavaScript 可以在其他地方找到该属性。其他地方是非常具体的。当 Array()
构造函数由 JavaScript 创建时,join()
方法被添加(除其他外)作为 Array()
的 prototype
属性的属性。
重申一下,如果您尝试访问不包含该属性的对象上的属性,JavaScript 将在 prototype
链中搜索该值。首先,它将查看创建对象的构造函数(例如,Array
),并检查其原型(例如,Array.prototype
)以查看是否可以在那里找到该属性。如果第一个原型对象没有该属性,则 JavaScript 会继续在初始构造函数后面的构造函数中沿链向上搜索。它可以一直做到这一点,直到链的末端。
链条的终点在哪里?让我们再次检查该示例,在 myArray
上调用 toLocaleString()
方法。
示例:sample40.html
<!DOCTYPE html><html lang="en"><body><script> // myArray and Array.prototype contain no toLocaleString() method. var myArray = ['foo', 'bar']; // toLocaleString() is actually defined at Object.prototype.toLocaleString console.log(myArray.toLocaleString()); // Logs 'foo,bar'. </script></body></html>
toLocaleString()
方法未在 myArray
对象中定义。因此,原型链接规则被调用,JavaScript 在 Array
构造函数原型属性中查找属性(例如,Array.prototype
)。它也不存在,因此再次调用链式规则,我们在 Object()
原型属性 (Object.prototype
) 中查找该属性。是的,它在那里找到。如果没有在那里找到它,JavaScript 将产生一个错误,指出该属性是 undefined
。
由于所有原型属性都是对象,因此链中的最终链接是 Object.prototype
。没有其他可以检查的构造函数原型属性。
前面有一整章将原型链分解为更小的部分,所以如果你完全不明白这一点,请阅读该章,然后再回到这个解释来巩固你的理解。从这篇简短的文章中,我希望您明白,当找不到属性时(并被视为 undefined
),JavaScript 将查看几个原型对象来确定属性是 undefined
。查找总是会发生,这个查找过程就是 JavaScript 处理继承以及简单属性查找的方式。
hasOwnProperty
验证对象属性不是来自原型链虽然 in
运算符可以检查对象的属性,包括来自原型链的属性,但 hasOwnProperty
方法可以检查对象的属性是否来自原型链。
在下面的示例中,我们想知道 myObject
是否包含属性 foo
,并且它没有从原型链继承该属性。为此,我们询问 myObject
是否有自己的名为 foo
的属性。
示例:sample41.html
<!DOCTYPE html><html lang="en"><body><script> var myObject = {foo: 'value'}; console.log(myObject.hasOwnProperty('foo')) // Logs true. // Versus a property from the prototype chain. console.log(myObject.hasOwnProperty('toString')); // Logs false. </script></body></html>
当您需要确定属性是对象的本地属性还是从原型链继承时,应该利用 hasOwnProperty
方法。
in
运算符检查对象是否包含给定属性in
运算符用于验证(true 或 false)对象是否包含给定属性。在此示例中,我们检查 foo
是否是 myObject
中的属性。
示例:sample42.html
<!DOCTYPE html><html lang="en"><body><script> var myObject = { foo: 'value' }; console.log('foo' in myObject); // Logs true. </script></body></html>
您应该知道 in
运算符不仅检查引用的对象中包含的属性,还检查对象通过 prototype
链继承的任何属性。因此,应用相同的属性查找规则,如果当前对象中没有该属性,则将在 prototype
链上搜索该属性。
这意味着上一个示例中的 myObject 实际上通过 prototype
链 (Object.prototype.toString
) 包含一个 toString
属性方法,即使我们没有指定一个(例如 myObject.toString) = 'foo'
)。
示例:sample43.html
<!DOCTYPE html><html lang="en"><body><script> var myObject = { foo: 'value' }; console.log('toString' in myObject); // Logs true. </script></body></html>
在最后一个代码示例中,toString 属性实际上并不位于 myObject 对象内部。但是,它是从 Object.prototype
继承的,因此 in
运算符得出的结论是 myObject
实际上具有继承的 toString()
属性方法。
for
in
循环枚举(循环)对象的属性通过使用 for in
,我们可以循环访问对象中的每个属性。在以下示例中,我们使用 for in
循环从 cody 对象中检索属性名称。
示例:sample44.html
<!DOCTYPE html><html lang="en"><body><script> var cody = { age: 23, gender: 'male' }; for (var key in cody) { // key is a variable used to represent each property name. // Avoid properties inherited from the prototype chain. if (cody.hasOwnProperty(key)) { console.log(key); } } </script></body></html>
for in
循环有一个缺点。它不仅会访问正在循环的特定对象的属性。它还将在循环中包含对象继承(通过原型链)的任何属性。因此,如果这不是期望的结果,而且大多数情况下都不是,我们必须在循环内使用简单的 if
语句来确保我们只访问我们正在循环的特定对象中包含的属性。这可以通过使用所有对象继承的 hasOwnProperty()
方法来完成。
在循环中访问属性的顺序并不总是在循环中定义它们的顺序。此外,您定义属性的顺序不一定是访问它们的顺序。
只有可枚举的属性(即在循环对象属性时可用)才显示在 for in
循环中。例如,构造函数属性将不会显示。可以使用 propertyIsEnumerable()
方法检查哪些属性是可枚举的。
您应该知道,执行 JavaScript 的环境(例如 Web 浏览器)通常包含所谓的主机对象。宿主对象不是 ECMAScript 实现的一部分,但在执行期间可作为对象使用。当然,宿主对象的可用性和行为完全取决于宿主环境提供的内容。
例如,在网络浏览器环境中,window/head 对象及其所有包含对象(不包括 JavaScript 提供的对象)都被视为宿主对象。
在下面的示例中,我检查 window
对象的属性。
示例:sample45.html
<!DOCTYPE html><html lang="en"><body><script> for (x in window) { console.log(x); // Logs all of the properties of the window/head object. } </script></body></html>
您可能已经注意到,本机 JavaScript 对象未在主机对象中列出。浏览器区分主机对象和本机对象是相当常见的。
就 Web 浏览器而言,所有托管对象中最著名的是用于处理 HTML 文档的界面,也称为 DOM。以下示例是列出浏览器环境提供的 window.document
对象内包含的所有对象的方法。
示例:sample46.html
<!DOCTYPE html><html lang="en"><body><script> for (x in window.document) { console.log(); } </script></body></html>
我希望您在这里了解的是 JavaScript 规范本身并不关心宿主对象,反之亦然。 JavaScript 提供的内容(例如,JavaScript 1.5、ECMA-262、第 3 版与 Mozilla 的 JavaScript 1.6、1.7、1.8、1.8.1、1.8.5)和主机环境提供的内容之间存在一条分界线,并且这两者不应该存在感到困惑。
运行 JavaScript 代码的主机环境(例如 Web 浏览器)通常提供头对象(例如 Web 浏览器中的 window 对象),其中语言的本机部分与主机对象(例如 一起存储) window.location
(Web 浏览器中的 window.location)和用户定义的对象(例如,您编写的在 Web 浏览器中运行的代码)。
有时,网络浏览器制造商作为 JavaScript 解释器的宿主,会在获得批准之前推出 JavaScript 版本或添加未来的 JavaScript 规范(例如,Mozilla 的 Firefox JavaScript 1.6、1.7、1.8、1.8.1) ,1.8.5)。
当需要认真操作和管理对象时,JavaScript 1.5 有所欠缺。如果您在 Web 浏览器中运行 JavaScript,那么当您需要比 JavaScript 1.5 提供的更多功能时,我想在这里大胆建议使用 Underscore.js。 Underscore.js 在处理对象时提供以下功能。
这些函数适用于所有对象和数组:
reduceRight()
摘み取る()
max()
分()
sortIndex()
toArray()
これらの関数はすべてのオブジェクトに適用されます:
キー()
値()
タップ()
isEqual()
isEmpty()
isElement()
isArray()
isArguments
isFunction()
isString()
is番号
isBoolean
は日付
isRegExp
はNaN
は未定義です
###結論は###
私がこのライブラリを気に入っているのは、ブラウザでサポートされている JavaScript への新しいネイティブ追加機能を利用しているだけでなく、それをサポートしていないブラウザにも同じ機能を提供しており、必要な場合を除いて JavaScript のネイティブ実装を変更する必要がないからです。
以上がオブジェクトとプロパティを操作するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。