検索
ホームページウェブフロントエンドjsチュートリアルJavaScript プログラムに継承機能を実装する方法 (グラフィック チュートリアル)

JavaScript はオブジェクト指向であると主張する言語であり、継承はオブジェクト指向の主要な機能です。興味のある学生はこちらをご覧ください。

概要 JavaScript のすべてのオブジェクトには独自の継承チェーンがあります。つまり、すべてのオブジェクトは、「プロトタイプ」オブジェクトと呼ばれる別のオブジェクトを継承します。 null を除いて、独自のプロトタイプ オブジェクトはありません。

プロトタイプ オブジェクトの重要性は、A オブジェクトが B オブジェクトのプロトタイプである場合、B オブジェクトは A オブジェクトのすべてのプロパティとメソッドを取得できることです。 Object.getPrototypof メソッドは、現在のオブジェクトのプロトタイプ オブジェクトを取得するために使用されます。

var p = Object.getPrototypeOf(obj);

上記のコードでは、オブジェクト p はオブジェクト obj のプロトタイプ オブジェクトです。

Object.create メソッドは、新しいオブジェクトを生成し、指定されたオブジェクトを継承するために使用されます。

var obj = Object.create(p);

上記のコードでは、新しく生成された obj オブジェクトのプロトタイプはオブジェクト p です。

非標準の __proto__ 属性 (前後 2 つのアンダースコア) は、オブジェクトのプロトタイプ オブジェクトをオーバーライドできます。ただし、この属性の使用はできる限り少なくし、代わりに Object.getPrototypeof() および Object.setPrototypeOf() を使用してプロトタイプ オブジェクトの読み取りおよび書き込みを行う必要があります。

var obj = {};
var p = {};

obj.__proto__ = p;
Object.getPrototypeOf(obj) === p // true

上記のコードは、__proto__ 属性を通じて p オブジェクトを obj オブジェクトのプロトタイプとして設定します。

これが実際的な例です。

var a = {x: 1};
var b = {__proto__: a};
b.x // 1

上記のコードでは、b オブジェクトは __proto__ 属性を通じてそのプロトタイプ オブジェクトを a オブジェクトに設定するため、b オブジェクトは a オブジェクトのすべての属性とメソッドを取得できます。 b オブジェクト自体には x 属性がありませんが、JavaScript エンジンは __proto__ 属性を通じてそのプロトタイプ オブジェクト a を見つけ、a の x 属性を読み取ります。

new コマンドは、コンストラクターを通じて新しいインスタンス オブジェクトを作成します。本質は、インスタンス オブジェクトのプロトタイプをコンストラクターのプロトタイプ属性にバインドし、インスタンス オブジェクトに対してコンストラクターを実行することです。

var o = new Foo();

// 等同于
var o = new Object();
o.__proto__ = Foo.prototype;
Foo.call(o);

プロトタイプ オブジェクト自体の __proto__ 属性は他のオブジェクトを指すこともでき、それによってレベルごとに「プロトタイプ チェーン」を形成します。

var a = { x: 1 };
var b = { __proto__: a };
var c = { __proto__: b };

c.x // 1

1 レベル上のプロトタイプ チェーンで特定の属性を検索すると、パフォーマンスに影響することに注意してください。探しているプロパティが上位レベルのプロトタイプ オブジェクト内にあるほど、パフォーマンスへの影響が大きくなります。存在しないプロパティを探す場合は、プロトタイプ チェーン全体が走査されます。

このアクションは を指します これがどこで定義されているかに関係なく、使用される場合、プロトタイプ オブジェクトではなく、常に現在のオブジェクトを指します。

var o = {
 a: 2,
 m: function(b) {
  return this.a + 1;
 }
};

var p = Object.create(o);
p.a = 12;

p.m() // 13

上記のコードでは、p オブジェクトの m メソッドは、そのプロトタイプ オブジェクト o から取得されます。このとき、m メソッド内の this オブジェクトは o ではなく、p を指します。

コンストラクターの継承 このセクションでは、あるコンストラクターに別のコンストラクターを継承させる方法を紹介します。

Shape コンストラクターがあると仮定します。

function Shape() {
 this.x = 0;
 this.y = 0;
}

Shape.prototype.move = function (x, y) {
 this.x += x;
 this.y += y;
 console.info('Shape moved.');
};
Rectangle构造函数继承Shape。

function Rectangle() {
 Shape.call(this); // 调用父类构造函数
}
// 另一种写法
function Rectangle() {
 this.base = Shape;
 this.base();
}

// 子类继承父类的方法
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

rect instanceof Rectangle // true
rect instanceof Shape // true

rect.move(1, 1) // 'Shape moved.'

上記のコードは、コンストラクターの継承が 2 つの部分に分かれていることを示しています。1 つはサブクラスが親クラスのコンストラクター メソッドを呼び出すことであり、もう 1 つはサブクラスのプロトタイプが親クラスのプロトタイプを指すことです。親クラス。

上記のコードでは、サブクラスは親クラスを全体として継承します。場合によっては、単一のメソッドの継承のみが必要な場合があります。この場合は、次の記述方法を使用できます。

ClassB.prototype.print = function() {
 ClassA.prototype.print.call(this);
 // some code
}

上記のコードでは、サブクラス B の print メソッドが最初に親クラス A の print メソッドを呼び出し、次に独自のコードをデプロイします。これは、親クラス A の print メソッドを継承することに相当します。

__proto__ 属性__proto__ 属性は、現在のオブジェクトのプロトタイプ オブジェクト、つまりコンストラクターのプロトタイプ属性を指します。

var obj = new Object();

obj.__proto__ === Object.prototype
// true
obj.__proto__ === obj.constructor.prototype
// true

上記のコードは、まず新しいオブジェクト obj を作成し、その __proto__ 属性はコンストラクター (Object または obj.constructor) のプロトタイプ属性を指します。したがって、両者を比較すると true が返されます。

したがって、インスタンスオブジェクトobjのプロトタイプオブジェクトを取得するには3つの方法があります。

  • obj.__proto__

  • obj.constructor.prototype

  • Object.getPrototypeOf(obj)

上記の 3 つのメソッドのうち、最初の 2 つはあまり信頼できません。最新の ES6 標準では、__proto__ 属性はブラウザーにのみデプロイする必要があり、他の環境にデプロイする必要はないと規定しています。プロトタイプ オブジェクトを手動で変更すると、Obj.constructor.prototype が無効になる場合があります。

var P = function () {};
var p = new P();

var C = function () {};
C.prototype = p;
var c = new C();

c.constructor.prototype === p // false

上記のコードでは、C コンストラクターのプロトタイプ オブジェクトが p に変更され、その結果、c.constructor.prototype が歪んでしまいました。したがって、プロトタイプ オブジェクトを変更する場合は、通常、同時にコンストラクター属性を設定する必要があります。

C.prototype = p;
C.prototype.constructor = C;

c.constructor.prototype === p // true

したがって、プロトタイプ オブジェクトを取得するには、3 番目の Object.getPrototypeOf メソッドを使用することをお勧めします。この方法は次のように使用されます。

var o = new Object();

Object.getPrototypeOf(o) === Object.prototype
// true

Object.getPrototypeOf メソッドを使用して、ブラウザーが __proto__ 属性をサポートしているかどうかを確認できます。古いブラウザーはこの属性をサポートしていません。

Object.getPrototypeOf({ __proto__: null }) === null

上記のコードは、オブジェクトの __proto__ 属性を null に設定し、次に Object.getPrototypeOf メソッドを使用してオブジェクトのプロトタイプを取得し、それが null に等しいかどうかを判断します。現在の環境が __proto__ 属性をサポートしている場合、この 2 つの比較結果は true になるはずです。

__proto__ 属性を使用すると、インスタンス オブジェクトのプロトタイプを簡単に設定できます。 machine、vehicle、car という 3 つのオブジェクトがあるとします。machine は vehicle のプロトタイプ、vehicle は car のプロトタイプです。これを設定するには 2 行のコードしか必要ありません。

vehicle.__proto__ = machine;
car.__proto__ = vehicle;

以下は、__proto__ 属性とconstructor.prototype 属性の 2 つのメソッドを通じて、プロトタイプ オブジェクトに定義された属性を読み取る例です。

Array.prototype.p = 'abc';
var a = new Array();

a.__proto__.p // abc
a.constructor.prototype.p // abc

明らかに、__proto__ の方がシンプルに見えます。

通过构造函数生成实例对象时,实例对象的__proto__属性自动指向构造函数的prototype对象。

var f = function (){};
var a = {};

f.prototype = a;
var o = new f();

o.__proto__ === a
// true

属性的继承属性分成两种。一种是对象自身的原生属性,另一种是继承自原型的继承属性。

对象的原生属性对象本身的所有属性,可以用Object.getOwnPropertyNames方法获得。

Object.getOwnPropertyNames(Date)
// ["parse", "arguments", "UTC", "caller", "name", "prototype", "now", "length"]

对象本身的属性之中,有的是可以枚举的(enumerable),有的是不可以枚举的。只获取那些可以枚举的属性,使用Object.keys方法。

Object.keys(Date) // []
hasOwnProperty()

hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。

Date.hasOwnProperty('length')
// true

Date.hasOwnProperty('toString')
// false

hasOwnProperty方法是JavaScript之中唯一一个处理对象属性时,不会遍历原型链的方法。

对象的继承属性用Object.create方法创造的对象,会继承所有原型对象的属性。

var proto = { p1: 123 };
var o = Object.create(proto);

o.p1 // 123
o.hasOwnProperty("p1") // false

获取所有属性判断一个对象是否具有某个属性(不管是自身的还是继承的),使用in运算符。

"length" in Date // true
"toString" in Date // true

获得对象的所有可枚举属性(不管是自身的还是继承的),可以使用for-in循环。

var o1 = {p1: 123};

var o2 = Object.create(o1,{
 p2: { value: "abc", enumerable: true }
});

for (p in o2) {console.info(p);}
// p2
// p1

为了在for...in循环中获得对象自身的属性,可以采用hasOwnProperty方法判断一下。

for ( var name in object ) {
 if ( object.hasOwnProperty(name) ) {
  /* loop code */
 }
}

获得对象的所有属性(不管是自身的还是继承的,以及是否可枚举),可以使用下面的函数。

function inheritedPropertyNames(obj) {
 var props = {};
 while(obj) {
  Object.getOwnPropertyNames(obj).forEach(function(p) {
   props[p] = true;
  });
  obj = Object.getPrototypeOf(obj);
 }
 return Object.getOwnPropertyNames(props);
}

用法如下:

inheritedPropertyNames(Date)
// ["caller", "constructor", "toString", "UTC", "call", "parse", "prototype", "__defineSetter__", "__lookupSetter__", "length", "arguments", "bind", "__lookupGetter__", "isPrototypeOf", "toLocaleString", "propertyIsEnumerable", "valueOf", "apply", "__defineGetter__", "name", "now", "hasOwnProperty"]

对象的拷贝如果要拷贝一个对象,需要做到下面两件事情。

确保拷贝后的对象,与原对象具有同样的prototype原型对象。
确保拷贝后的对象,与原对象具有同样的属性。
下面就是根据上面两点,编写的对象拷贝的函数。

function copyObject(orig) {
 var copy = Object.create(Object.getPrototypeOf(orig));
 copyOwnPropertiesFrom(copy, orig);
 return copy;
}

function copyOwnPropertiesFrom(target, source) {
 Object
 .getOwnPropertyNames(source)
 .forEach(function(propKey) {
  var desc = Object.getOwnPropertyDescriptor(source, propKey);
  Object.defineProperty(target, propKey, desc);
 });
 return target;
}

多重继承JavaScript不提供多重继承功能,即不允许一个对象同时继承多个对象。但是,可以通过变通方法,实现这个功能。

function M1(prop) {
 this.hello = prop;
}

function M2(prop) {
 this.world = prop;
}

function S(p1, p2) {
 this.base1 = M1;
 this.base1(p1);
 this.base2 = M2;
 this.base2(p2);
}
S.prototype = new M1();

var s = new S(111, 222);
s.hello // 111
s.world // 222

上面代码中,子类S同时继承了父类M1和M2。当然,从继承链来看,S只有一个父类M1,但是由于在S的实例上,同时执行M1和M2的构造函数,所以它同时继承了这两个类的方法。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

详细介绍在JS中Map和ForEach的区别

js装饰设计模式学习心得(详细解答)

详解解读JS数值Number类型(图文教程)

以上がJavaScript プログラムに継承機能を実装する方法 (グラフィック チュートリアル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

PythonとJavaScriptにはそれぞれ独自の利点があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1. Pythonは、データサイエンスやバックエンド開発に適した簡潔な構文を備えた学習が簡単ですが、実行速度が遅くなっています。 2。JavaScriptはフロントエンド開発のいたるところにあり、強力な非同期プログラミング機能を備えています。 node.jsはフルスタックの開発に適していますが、構文は複雑でエラーが発生しやすい場合があります。

JavaScriptのコア:CまたはCの上に構築されていますか?JavaScriptのコア:CまたはCの上に構築されていますか?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc;それは、解釈されていることを解釈しました。

JavaScriptアプリケーション:フロントエンドからバックエンドまでJavaScriptアプリケーション:フロントエンドからバックエンドまでMay 04, 2025 am 12:12 AM

JavaScriptは、フロントエンドおよびバックエンド開発に使用できます。フロントエンドは、DOM操作を介してユーザーエクスペリエンスを強化し、バックエンドはnode.jsを介してサーバータスクを処理することを処理します。 1.フロントエンドの例:Webページテキストのコンテンツを変更します。 2。バックエンドの例:node.jsサーバーを作成します。

Python vs. Javascript:どの言語を学ぶべきですか?Python vs. Javascript:どの言語を学ぶべきですか?May 03, 2025 am 12:10 AM

PythonまたはJavaScriptの選択は、キャリア開発、学習曲線、エコシステムに基づいている必要があります。1)キャリア開発:Pythonはデータサイエンスとバックエンド開発に適していますが、JavaScriptはフロントエンドおよびフルスタック開発に適しています。 2)学習曲線:Python構文は簡潔で初心者に適しています。 JavaScriptの構文は柔軟です。 3)エコシステム:Pythonには豊富な科学コンピューティングライブラリがあり、JavaScriptには強力なフロントエンドフレームワークがあります。

JavaScriptフレームワーク:最新のWeb開発のパワーJavaScriptフレームワーク:最新のWeb開発のパワーMay 02, 2025 am 12:04 AM

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

JavaScript、C、およびブラウザの関係JavaScript、C、およびブラウザの関係May 01, 2025 am 12:06 AM

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

node.jsは、型を使用してストリーミングしますnode.jsは、型を使用してストリーミングしますApr 30, 2025 am 08:22 AM

node.jsは、主にストリームのおかげで、効率的なI/Oで優れています。 ストリームはデータを段階的に処理し、メモリの過負荷を回避します。大きなファイル、ネットワークタスク、リアルタイムアプリケーションの場合。ストリームとTypeScriptのタイプの安全性を組み合わせることで、パワーが作成されます

Python vs. JavaScript:パフォーマンスと効率の考慮事項Python vs. JavaScript:パフォーマンスと効率の考慮事項Apr 30, 2025 am 12:08 AM

PythonとJavaScriptのパフォーマンスと効率の違いは、主に以下に反映されています。1)解釈された言語として、Pythonはゆっくりと実行されますが、開発効率が高く、迅速なプロトタイプ開発に適しています。 2)JavaScriptはブラウザ内の単一のスレッドに限定されていますが、マルチスレッドおよび非同期I/Oを使用してnode.jsのパフォーマンスを改善でき、両方とも実際のプロジェクトで利点があります。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター