2017-07-13 13 views
2

Intl.DateTimeFormatの動作がわかりません。Intl.DateTimeFormatをJavaScriptオブジェクトとして理解する

JavaScriptオブジェクトから予想される動作は公開されません。 私はなぜそれを理解したいですか?

DateTimeFormatformatメソッドをオーバーライドできないことを次のスニペットで示します。これはどのように可能ですか?また、原型継承を経てDateTimeFormat由来

const itDateTimeFormat1 = new window.Intl.DateTimeFormat('it-CH'); 
const originalFormat = itDateTimeFormat1.format; 
itDateTimeFormat1.format = function(date){ return 'Overriden! ' + originalFormat(date)}; 
console.log(itDateTimeFormat1.format(new Date())); // -> 13/7/2017 

ことはできないようです。次のスニペットは、エラーがスローされます:

const itDateTimeFormat2 = new window.Intl.DateTimeFormat('it-CH'); 
const wrappedDateTimeFormat = Object.create(itDateTimeFormat2); 
wrappedDateTimeFormat.format = function(date){ return 'Overriden! ' }; 
console.log(wrappedDateTimeFormat.format(new Date())); 
// Firefox: 
// TypeError: Intl.DateTimeFormat.prototype.format called on value that's not an object initialized as a DateTimeFormat 
// Chrome: 
// Uncaught TypeError: Method format called on incompatible receiver #<DateTimeFormat> 

はなぜDateTimeFormat「通常」のJavaScriptオブジェクトのように動作されていませんか?

DateTimeFormatは、どのようにメソッドのオーバーライドを防止できますか?

DateTimeFormatは派生オブジェクトのオーバーライドをどのように防ぐことができますか?

答えて

2

オリジナルの答え

まあ、それは組み込みのオブジェクトなので、凍らせておくと良いです。 しかし、ちょうどこのようなことをJavascriptでObject.definePropertyとすることができます。

次のスニッパを参照してください。 writeable: falseでプロパティの上書きを防止できます。 (JS 5.1を使用しました)

var MyCoolConstructor = function() { 

    Object.defineProperty(this, 'nonWriteable', { 
    enumerable: false, 
    configurable: false, 
    writable: false, 
    value: function() {return 42;} 
    }); 
}; 

var instance = new MyCoolConstructor(); 


console.log(instance.nonWriteable()); //42 
instance.nonWriteable = function() {return 'overriden';} 
console.log(instance.nonWriteable()); //42 

プロトタイプの継承を防ぐにはどうすればよいですか?

この簡単なスニペットを確認してください。現在のコンテキストがあなたのコンストラクタと同じプロトタイプを持っているかどうかだけを確認できます。

var MyCoolConstructor = function() { 
    this.foo = function() { 
    if (Object.getPrototypeOf(this) === MyCoolConstructor.prototype) { 
     return 42; 
    } else { 
     throw new Error('bad this'); 
    } 
    }; 
}; 

var instance = new MyCoolConstructor(); 
console.log(instance.foo()); 
//42 

var instance2 = Object.create(instance); 
console.log(instance2.foo()) 
//Bad this 

編集2

派生オブジェクトのメソッドオーバーライドも は、それらがプロパティ設定を導出する、同様に防止することができます。あなたが本当になめらかを上書きしたい場合は チェック2 ... 3でハックをクールではない

var MyCoolConstructor = function() { 
    Object.defineProperty(this, 'foo', { 
    value: function() { 
     if (Object.getPrototypeOf(this) === MyCoolConstructor.prototype) { 
     return 42; 
     } else { 
     throw new Error('bad this'); 
     } 
    }, 
    writeable: false 
    }); 
}; 

var instance = new MyCoolConstructor(); 
console.log(instance.foo()); 
//42 

var derivedInstance = Object.create(instance); 
derivedInstance.foo = function() { 
    return 'overriden'; 
}; 
console.log(derivedInstance.foo()); 
//Bad this. Can't be overridden because foo property is not writeable 

2以前の組み合わせです。このスニペット.. 1 ..

Object.definePropertyが救助に来ます。

const itDateTimeFormat2 = new window.Intl.DateTimeFormat('it-CH'); 
const wrappedDateTimeFormat = Object.create(itDateTimeFormat2); 
Object.defineProperty(wrappedDateTimeFormat, 'format', {value: function(date) { return 'Overridden!' + date.toString(); }}) 
wrappedDateTimeFormat.format() 
//"Overriden! ..." 

我々は例を見てきたように結論

。システムオブジェクトは、通常設定されたjavascriptオブジェクトのように振る舞います。

+0

ありがとうございます。しかし、 'DateTimeFormat'の場合、派生オブジェクトは独自の' format'メソッドを提供できません(私は質問の2番目のスニペットを調整しました)。そんなことがあるものか? – jbandi

+0

@jbandiは私に考えさせましょう:)私はこの振る舞いのスニペットも提供しようとします – Andrey

+0

すばらしい例!ありがとう! – jbandi

関連する問題