導入
この記事で導入された4つのコードの再利用モードは、ベストプラクティスであり、プログラミングプロセス中に全員に推奨されます。
パターン1:プロトタイプの継承
プロトタイプの継承は、親オブジェクトを継承の目的を達成するために、子オブジェクトのプロトタイプにすることです。
コードコピーは次のとおりです。
関数オブジェクト(o){
関数f(){
}
f.prototype = o;
新しいf()を返します。
}
//継承する親オブジェクト
var parent = {
名前:「パパ」
};
//新しいオブジェクト
var child = object(parent);
// テスト
console.log(child.name); //「パパ」
//親コンストラクター
function person(){
//「独自の」プロパティ
this.name = "adam";
}
//プロトタイプに新しい属性を追加します
person.prototype.getName = function(){
this.nameを返します。
};
//新しい人を作成します
var papa = new person();
// 継承
var kid = object(papa);
console.log(kid.getname()); //「アダム」
//親コンストラクター
function person(){
//「独自の」プロパティ
this.name = "adam";
}
//プロトタイプに新しい属性を追加します
person.prototype.getName = function(){
this.nameを返します。
};
// 継承
var kid = object(person.prototype);
console.log(typeof kid.getName); //「関数」。プロトタイプで定義されているため
console.log(typeof kid.name); //プロトタイプのみが継承されるため、「未定義」
同時に、ECMAScript5は、オブジェクトを継承するためにobject.createと呼ばれる同様の方法も提供します。使用法は次のとおりです。
コードコピーは次のとおりです。
/* ecmascript5の新しいバージョンを使用して機能を提供します*/
var child = object.create(parent);
var child = object.create(parent、{
年齢:{値:2} // ecma5記述子
});
console.log(child.hasownproperty( "age")); // 真実
さらに、プロパティは、より微調整された方法で2番目のパラメーターで定義することもできます。
コードコピーは次のとおりです。
//最初に、新しいオブジェクトマンを定義します
var man = object.create(null);
//次に、プロパティを含む構成設定を作成します
//プロパティは、書き込み可能、列挙可能、構成可能に設定されています
var config = {
手紙:本当、
列挙可能:本当、
設定可能:true
};
//通常、object.defineProperty()を使用して新しいプロパティを追加します(ecmascript5サポート)
//ここで、便宜上、カプセル化関数をカスタマイズします
var defineProp = function(obj、key、value){
config.value = value;
object.defineProperty(obj、key、config);
}
defineProp(man、 'car'、 'delorean');
DefineProp(Man、 'dob'、 '1981');
DefineProp(man、 'ard'、false);
したがって、継承は行うことができます:
コードコピーは次のとおりです。
var driver = object.create(man);
defineProp(driver、 'topspeed'、 '100mph');
driver.topspeed // 100mph
しかし、注意すべきことは1つあります。つまり、object.create(null)によって作成されたオブジェクトのプロトタイプは未定義です。つまり、メソッドのトストリングと価値はありません。したがって、アラート(man);大丈夫です。
モード2:継承のすべての属性をコピーします
この方法での継承は、親オブジェクトのすべてのプロパティを子オブジェクトにコピーすることです。一般に、子オブジェクトは親オブジェクトのデータを使用できます。
まず、浅いコピーの例を見てみましょう。
コードコピーは次のとおりです。
/*浅いコピー*/
関数拡張(親、子){
var i;
子=子|| {};
(私は親の){
if(parent.hasownproperty(i)){
子[i] =親[i];
}
}
子供を返します。
}
var Dad = {name: "Adam"};
var kid = extend(dad);
console.log(kid.name); //「アダム」
var Dad = {
カウント:[1、2、3]、
読み取り:{Paper:true}
};
var kid = extend(dad);
kid.counts.push(4);
console.log(dad.counts.tostring()); //「1,2,3,4」
console.log(dad.reads === kid.reads); // 真実
コードの最後の行では、お父さんと子供の読み取りが同じであることがわかります。つまり、同じ参照を使用します。これは浅いコピーによって引き起こされる問題です。
深いコピーを見てみましょう:
コードコピーは次のとおりです。
/*ディープコピー*/
関数extendep(親、子){
var i、
toStr = object.prototype.toString、
ASTR = "[オブジェクトアレイ]";
子=子|| {};
(私は親の){
if(parent.hasownproperty(i)){
if(typeof parent [i] === 'object'){
child [i] =(tostr.call(parent [i])=== astr)? []:{};
extenddeep(parent [i]、child [i]);
} それ以外 {
子[i] =親[i];
}
}
}
子供を返します。
}
var Dad = {
カウント:[1、2、3]、
読み取り:{Paper:true}
};
var kid = extenddeep(dad);
kid.counts.push(4);
console.log(kid.counts.tostring()); //「1,2,3,4」
console.log(dad.counts.tostring()); //「1,2,3」
console.log(dad.reads === kid.reads); // 間違い
kid.reads.paper = false;
深いコピーの後、2つの値はもはや等しくありません、ビンゴ!
モード3:ミックスイン
混合されるのは、オブジェクトの1つまたは複数の(またはすべての)プロパティ(または方法)を別のオブジェクトにコピーすることです。例を挙げましょう:
コードコピーは次のとおりです。
function mix(){
var arg、prop、child = {};
for(arg = 0; arg <arguments.length; arg += 1){
for(arguments [arg]の小道具){
if(arguments [arg] .hasownproperty(prop)){
child [prop] = arguments [arg] [prop];
}
}
}
子供を返します。
}
var cake = mix(
{卵:2、大きい:true}、
{バター:1、塩漬け:true}、
{小麦粉: '3カップ'}、
{シュガー:「確かに!」 }
);
Console.dir(ケーキ);
ミックス関数は、新しいオブジェクトを生成するために子オブジェクトに渡されたすべてのパラメーターの子属性をコピーします。
では、どのようにしていくつかの属性を混ぜたいのでしょうか?それをする方法は?実際、追加のパラメーターを使用して、混合(子、親、Method1、Method2)など、混合する必要があるプロパティを定義して、親のMethod1とMethod2のみを子供に混ぜることができます。コード:
コードコピーは次のとおりです。
// 車
var car = function(settings){
this.model = settings.model || 「モデルは提供されていません」;
this.colour = settings.colour || 「色は提供されていません」;
};
// MIXIN
var mixin = function(){};
mixin.prototype = {
driveforward:function(){
console.log( 'drive forward');
}、
drivebackward:function(){
console.log( 'drive backward');
}
};
//定義された2つのパラメーターは、オブジェクトが混合されている(reciving)と混合されているオブジェクト(授与)です。
function augment(receiveobj、divingobj){
//指定されたメソッド名が提供されている場合、3つの追加パラメーターがあります
if(引数[2]){
for(var i = 2、len = arguments.length; i <len; i ++){
Receivingobj.prototype [arguments [i]] = bivingobj.prototype [arguments [i]];
}
}
// 3番目のパラメーターまたはより多くのパラメーターを指定しない場合、すべてのメソッドが混合されます
それ以外 {
for(var methodname in divingobj.prototype){
//受信オブジェクトが混合する名前が含まれていないことを確認するので、それが含まれている場合、それは混合されません
if(!recemingobj.prototype [methodname]){
ReceivingObj.Prototype [MethodName] = bivingObj.Prototype [MethodName];
}
}
}
}
//車の属性を混ぜますが、値は「ドライブフォーワード」と「ドライブバックワード」と混合されます*/
Augment(car、mixin、 'driveforward'、 'drivebackward');
//新しいオブジェクトカーを作成します
var車両=新しい車({モデル: 'フォードエスコート'、色: 'blue'});
//混合が正常に取得されたかどうかをテストする方法
beher.driveforward();
behile.drivebackward();
この方法は、より柔軟に使用できます。
パターン4:借入方法
1つのオブジェクトは、別のオブジェクトの1つまたは2つの方法を借用し、これら2つのオブジェクト間に直接的な接続はありません。これ以上説明する必要はありません。コードを使用して説明するだけです。
コードコピーは次のとおりです。
var one = {
名前:「オブジェクト」、
Say:function(Greet){
Greet + '、' + this.nameを返します。
}
};
// テスト
console.log(one.say( 'hi')); //「こんにちは、オブジェクト」
var two = {
名前:「別のオブジェクト」
};
console.log(one.say.apply(2、['hello'])); //「こんにちは、別のオブジェクト」
//変数に言うと、これはグローバル変数を指します
var says = one.say;
console.log(eak( 'hoho')); //「Hoho、未定」
//コールバック関数コールバックを渡します
var yetanother = {
名前:「さらに別のオブジェクト」、
方法:function(callback){
return callback( 'hola');
}
};
console.log(yetanother.method(one.say)); //「ホラ、未定」
関数バインド(o、m){
return function(){
return m.apply(o、[] .slice.call(arguments));
};
}
var twosay = bind(2、1.say);
console.log(twosay( 'yo')); //「よ、別のオブジェクト」
// ecmascript 5は、function.prototypeにbind()メソッドを追加して、apply()とcall()を使いやすくします。
if(typeof function.prototype.bind === '未定義'){
function.prototype.bind = function(thisarg){
var fn =これ、
slice = array.prototype.slice、
args = slice.call(arguments、1);
return function(){
return fn.apply(thisarg、args.concat(slice.call(arguments)));
};
};
}
var twosay2 = one.say.bind(2);
console.log(twosay2( 'bonjour')); //「Bonjour、別のオブジェクト」
var twosay3 = one.say.bind(2、 'enchanté');
console.log(twosay3()); //「エンチャント、別のオブジェクト」
要約します
要約する必要はありません。