4

カスタムオブジェクトを作成するときに、ネイティブの js 関数を上書きするメソッド (私の場合は「読み取り」、「書き込み」、「保存」) を指定しても安全ですか?

問題のオブジェクトは、DOM に書き込む必要はありません (または、失われる関数を使用する必要はありません)。これらのメソッド名は理想的なものなので、気になったのですが、これに対する明確な答えを見つけるのに苦労したことに驚きました。以下の例。ありがとう。

/**
 * Ticket class
 * @param category
 * @param issuedBy
 * @param reissuable If true, lock cannot be overridden by the same method that locked it
 * @returns {Ticket}
 * @constructor
 */
Ticket = function (category, issuedBy, reissuable) {
    //properties
    this.id = Date.now().toString();
    this.category = category;
    this.resolved = false;
    this.issuingMethod = issuedBy;
    this.reissuable = reissuable === true;
    this.data = {};

    //methods
    this.resolve = function () { return this.resolved = true;};
    this.read = function (dataPath) { // find dataPath in this.data }
    this.write = function (dataPath, value) { // add value to dataPath of this.data}

    return this;
};
4

2 に答える 2

4

完全に安全ではありません。コンストラクターが なしnewで呼び出されるとthis、グローバル オブジェクトを指します。

var ticket = Ticket(); //this.document will point to the global document object

コードを理解するための鍵thisは、さまざまなことを意味する特別なキーワードである which を使用することです。

  • 関数内にない場合はwindow( <script>alert(this.name)</script>)を意味します。
  • オブジェクトがアタッチされていないスタンドアロン関数として呼び出された場合、( alert())はオブジェクトthisを指しますwindow
  • ドット構文(ticket.resolve())で呼び出された場合this、ドット ( ) の左側にあるオブジェクトを指しますticket
  • コンストラクター ( new Ticket)として呼び出されると、プロトタイプ チェーンにthis含まれる新しい空のオブジェクトになります。Ticket.prototype
  • inline HTML handlers( onclick="alert(this.id)")から呼び出されthisた場合、イベントを追加した HTML 要素を指します。
  • や AJAX コールバックなどsetTimeoutの関数から呼び出されると、通常は次の場所を指します。setIntervalthiswindow
  • applyまたはを使用して関数を呼び出す場合call、何をthis呼び出すかを指定できます。
  • Function.bind通常、関数が正しい方法で呼び出されるようにするために使用できます

を呼び出す場合var ticket = Ticket()、すべてのコードthis.name = 'something'は既存のグローバル変数 (この場合nameはウィンドウの ) を作成または上書きします。

この問題が気になる場合は、次の手順を実行することでこの問題を軽減できます。

    Ticket = function (category, issuedBy, reissuable) {
    if (!this instanceof Ticket) { // called as a function
         return new Ticket(category, issusedBy, reissuable);
    }
    //properties
    this.id = Date.now().toString();

一般的な方法で行うには、このリンクhttp://js-bits.blogspot.com/2010/08/constructors-without-using-new.htmlを参照してください。

これはおそらく不必要な定型コードであり、コード規則に従ってそれらを強制することで回避できることに注意してください

于 2014-05-13T23:00:20.567 に答える
2

Object.prototype提供されているコード サンプルでは、​​ネイティブメソッドをオーバーライドしていません。Object.prototypeただし、注意しないと、継承されたネイティブ メソッドをオーバーライドする可能性があります。

function MyObject() {}

MyObject.prototype.hasOwnProperty = function () { return true; };

new MyObject().hasOwnProperty('test'); //true

明らかに誤解を招く可能性があり、この場合、ネイティブ関数をオーバーライドするのではなく、ドメイン内で同様の意味を持つ別の関数名を選択しますObject.prototype.hasOwnProperty

別の回答では、newキーワードなしでコンストラクターを呼び出すと、グローバル ネイティブ変数がオーバーライドされる可能性があると言われています。これは非常に正しいことですが、ネイティブ グローバル変数をオーバーライドする可能性があるだけでなく、はるかに多くの悪影響があります。JSHint などの優れたツールを使用してコードを lint することで、これらの間違いを回避できます。

于 2014-05-13T22:57:16.897 に答える