私は確かに私が何をしようとしています何のために名前があり、私はこれは前に頼まれていると確信していますが、私は、既存の答えを見つけるのに苦労していますよ-私は正しい用語を探しておりませんので、おそらく。私はと呼ばれるJavaScript関数持ちextend()
に似てObject.assign()
、マージには、一緒にオブジェクト-私はへのアクセスを持っていないObject.assign
私の現在の実装では。
function extend(target) {
for (var i = 1; i < arguments.length; ++i) {
if (typeof arguments[i] !== 'object') {
continue;
}
for (var j in arguments[i]) {
if (arguments[i].hasOwnProperty(j)) {
if (typeof arguments[i][j] === 'object') {
target[j] = extend({}, target[j], arguments[i][j]);
}
else if (!target.hasOwnProperty(j)) {
target[j] = arguments[i][j];
}
}
}
}
return target;
}
これは私が使用してそれを呼び出す場合は正常に動作extend(target, defaults)
の内容をマージしますそのdefaults
中にtarget
、任意の既存のキーを上書きせずにtarget
(彼らはオブジェクトであり、それらがマージされない限りは)。
私が実際に使用して、これを呼び出す方法を探していますtarget.extend(defaults)
最初ので、target
へのパラメータはextend
、実際として暗示されますthis
。私は交換することにより機能を書き換えしようとしていtarget
てthis
、それは望ましい結果を持っていない(私は再帰を変更した方法が間違っていると思います)。
target.extend = function() {
...
this[j] = this.extend(this[j], arguments[i][j]);
...
return this;
};
任意のポインタ(または既存の回答への言及は)感謝していただければ幸いです。
あなたはする機能を割り当てることができObject.prototype
、あなたが探している機能を実現するために:
Object.defineProperty(
Object.prototype,
'extend',
{
enumerable: false,
value: function() {
const target = this;
for (var i = 0; i < arguments.length; ++i) {
if (typeof arguments[i] !== 'object') {
continue;
}
for (var j in arguments[i]) {
if (arguments[i].hasOwnProperty(j)) {
if (typeof arguments[i][j] === 'object') {
target[j] = extend({}, target[j], arguments[i][j]);
}
else if (!target.hasOwnProperty(j)) {
target[j] = arguments[i][j];
}
}
}
}
return target;
}
}
);
const obj = { foo: 'foo' };
obj.extend({ bar: 'bar' });
console.log(obj);
または、コードの束をクリーンアップ:
Object.defineProperty(
Object.prototype,
'extend',
{
enumerable: false,
value: function(...args) {
const target = this;
for (const arg of args) {
for (const [key, val] of Object.entries(arg)) {
if (typeof val === 'object') extend(target[key], val);
else target[key] = val;
}
}
}
}
);
const obj = { foo: 'foo' };
obj.extend({ bar: 'bar' });
console.log(obj);
しかし、これはある悪い考え、それは名前の衝突や混乱コードにつながる可能性があるため、。以下のようなオブジェクトがあります場合はどう
const obj = { extend: true };
何をしないobj.extend
、その後のですか?(それは自身のプロパティを参照しますが、これはスクリプトライターは、スタンドアロン機能を持っている。よりよい心配する必要がありますものではありません。)
これは、まったく同じオブジェクトのヘルパーメソッドの多くは、上に存在する理由ですObject
コンストラクタ、およびありませんでObject.prototype
。たとえば、あなたが呼び出しObject.assign
、またはObject.defineProperty
、ではありません obj.assign
かobj.defineProperty
。
あなたが唯一の特定のオブジェクトにこの機能が必要な場合は、呼び出すことによって、プロトタイプの汚染を避けることができObject.defineProperty
、それらのオブジェクトに:
const addExtend = obj => {
Object.defineProperty(
obj,
'extend',
{
enumerable: false,
value: function(...args) {
const target = this;
for (const arg of args) {
for (const [key, val] of Object.entries(arg)) {
if (typeof val === 'object') extend(target[key], val);
else target[key] = val;
}
}
}
}
);
};
const obj = { foo: 'foo' };
addExtend(obj);
obj.extend({ bar: 'bar' });
console.log(obj);
あなたは、オブジェクトが作成される場所を管理している場合は、あなたが使用できるObject.create
ようにextend
、プロトタイプから継承されたメソッドです。
const objExtendProto = {};
Object.defineProperty(
objExtendProto,
'extend',
{
enumerable: false,
value: function(...args) {
const target = this;
for (const arg of args) {
for (const [key, val] of Object.entries(arg)) {
if (typeof val === 'object') extend(target[key], val);
else target[key] = val;
}
}
}
}
);
const obj = Object.create(objExtendProto);
obj.foo = 'foo';
obj.extend({ bar: 'bar' });
console.log(obj);