ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript でのオブジェクト作成の詳細な紹介

JavaScript でのオブジェクト作成の詳細な紹介

零下一度
零下一度オリジナル
2017-06-28 13:43:131015ブラウズ

この記事は主に JavaScript で作成されたオブジェクト に関する情報を詳しく紹介します。興味のある方は参考にしてください。

作成された各オブジェクトに対してプロトタイプを設定します。 。

obj.xxx を使用してオブジェクトのプロパティにアクセスすると、JavaScript エンジンはまず現在のオブジェクトのプロパティを検索します。まだ見つからない場合は、そのプロトタイプ オブジェクトに移動します。オブジェクトのプロトタイプ オブジェクトまで遡り、最終的に、それが見つからなかった場合は、未定義のみを返すことができます。
たとえば、Array オブジェクトを作成します:

var arr = [1, 2, 3];

プロトタイプ チェーンは次のとおりです:

arr ----> Object.prototype ---->
Array.prototype は、indexOf()、shift() およびその他のメソッドを定義しているため、すべての Array オブジェクトでこれらのメソッドを直接呼び出すことができます。

関数を作成するとき:

function foo() {
  return 0;
}

関数もオブジェクトであり、そのプロトタイプ チェーンは次のとおりです:

foo ----> Function.prototype ----> ; null


Function.prototype には apply() などのメソッドが定義されているため、すべての関数が apply() メソッドを呼び出すことができます。


プロトタイプチェーンが長いと、ルックアップに時間がかかるため、オブジェクトのプロパティへのアクセスが遅くなると思われがちなので、プロトタイプチェーンが長くなりすぎないように注意してください。


コンストラクター
JavaScript は、{ ... }

を直接使用してオブジェクト

を作成するだけでなく、コンストラクター メソッドを使用してオブジェクトを作成することもできます。その使用方法は、まずコンストラクターを定義することです:

function Student(name) {
  this.name = name;
  this.hello = function () {
    alert('Hello, ' + this.name + '!');
  }
}
これは普通の関数ではないのかと疑問に思うでしょう。


これは確かに普通の関数ですが、JavaScript では、キーワード new を使用してこの関数を呼び出し、オブジェクトを返すことができます:

var xiaoming = new Student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // Hello, 小明!

new を書かないと、これは普通の関数であり、未定義を返すことに注意してください。ただし、 new が書き込まれると、それはコンストラクターになり、それにバインドされた this は新しく作成されたオブジェクトを指し、デフォルトで this を返します。つまり、最後に return this を記述する必要はありません。


新しく作成された xiaoming のプロトタイプ チェーンは次のとおりです:


xiaoming ----> Student.prototype ----> Object.prototype ----> null


たとえば、xiaoming のプロトタイプは関数 Student のプロトタイプを指します。 xiaohong と xiaojun を再度作成すると、これらのオブジェクトのプロトタイプは xiaoming と同じになります。

new Student() で作成されたオブジェクトは、関数 Student 自体を指すコンストラクター属性もプロトタイプから取得します。これらの厄介な関係を図で表すと次のようになります:



赤い矢印はプロトタイプチェーンです。 Student.prototype が指すオブジェクトは、xiaoming と xiaohong のプロトタイプ オブジェクトであることに注意してください。このプロトタイプ オブジェクト自体には、Student 関数自体を指す属性コンストラクターがあります。
さらに、関数 Student には、たまたま xiaoming と xiaohong のプロトタイプ オブジェクトを指す属性 prototype がありますが、xiaoming オブジェクトと xiaohong オブジェクトには属性 proto がありませんが、proto の非標準的な使用法を使用して表示できます。 。

今、xiaoming や xiaohong などのオブジェクトは Student から「継承」していると考えられます。

しかし、まだ小さな問題があります。注意してください。

xiaoming.constructor === Student.prototype.constructor; // true
Student.prototype.constructor === Student; // true

Object.getPrototypeOf(xiaoming) === Student.prototype; // true

xiaoming instanceof Student; // true

xiaoming と xiaohong は名前が異なりますが、これは正しいです。そうしないと、誰が誰であるかを区別できません。

xiaoming と xiaohong のそれぞれの hello は 1 つの機能ですが、機能名とコードは同じですが、2 つの異なる機能です。

new Student() を通じて多くのオブジェクトを作成する場合、これらのオブジェクトの hello 関数は実際には同じ関数を共有するだけで済み、メモリを大幅に節約できます。

オブジェクト属性の検索原則に従って、作成されたオブジェクトに hello 関数を共有させるには、hello 関数を xiaoming オブジェクトと xiaohong オブジェクトの共通プロトタイプ (Student.prototype) に移動するだけです:


コードを次のように変更します。

xiaoming.name; // '小明'
xiaohong.name; // '小红'
xiaoming.hello; // function: Student.hello()
xiaohong.hello; // function: Student.hello()
xiaoming.hello === xiaohong.hello; // false

new を使用してプロトタイプベースの JavaScript オブジェクトを作成するのはとても簡単です。

新規書き忘れたらどうすればいいですか

如果一个函数被定义为用于创建对象的构造函数,但是调用时忘记了写new怎么办?
在strict模式下,this.name = name将报错,因为this绑定为undefined,在非strict模式下,this.name = name不报错,因为this绑定为window,于是无意间创建了全局变量name,并且返回undefined,这个结果更糟糕。
所以,调用构造函数千万不要忘记写new。为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写,而普通函数首字母应当小写,这样,一些语法检查工具如jslint将可以帮你检测到漏写的new。
最后,我们还可以编写一个createStudent()函数,在内部封装所有的new操作。一个常用的编程模式像这样:


function Student(props) {
  this.name = props.name || '匿名'; // 默认值为'匿名'
  this.grade = props.grade || 1; // 默认值为1
}

Student.prototype.hello = function () {
  alert('Hello, ' + this.name + '!');
};

function createStudent(props) {
  return new Student(props || {})
}

这个createStudent()函数有几个巨大的优点:一是不需要new来调用,二是参数非常灵活,可以不传,也可以这么传:


var xiaoming = createStudent({
  name: '小明'
});

xiaoming.grade; // 1

如果创建的对象有很多属性,我们只需要传递需要的某些属性,剩下的属性可以用默认值。由于参数是一个Object,我们无需记忆参数的顺序。如果恰好从JSON拿到了一个对象,就可以直接创建出xiaoming。

练习

请利用构造函数定义Cat,并让所有的Cat对象有一个name属性,并共享一个方法say(),返回字符串'Hello, xxx!':

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

以上がJavaScript でのオブジェクト作成の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。