2017-05-18 19 views
-8

私は、次のコードを実行すると、私はエラーを取得:プロパティを再定義できないのはなぜですか?

TypeError: Cannot redefine property: isBoolean

は、なぜ私はそれらのプロパティを再定義することはできませんか?

function isBoolean() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "boolean") { 
 
    return true; 
 
    } else { 
 
    return false; 
 
    } 
 
} 
 

 
function isString() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "string") { 
 
    return true; 
 
    } else { 
 
    return false; 
 
    } 
 
} 
 

 
function isNumber() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (onoff) { 
 
    if (value === Infinity) { return Infinity; } 
 
    } 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "number") { 
 
    return true; 
 
    } else { 
 
    return false; 
 
    } 
 
} 
 

 
function isArray() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    return Array.isArray(value); 
 
} 
 

 
Object.defineProperties(window, { 
 
// "thisType" : { enumerable: false }, 
 
    "isBoolean": { enumerable: false }, 
 
    "isString" : { enumerable: false }, 
 
    "isNumber" : { enumerable: false }, 
 
    "isArray" : { enumerable: false }, 
 
});

+2

郵便すべてのコード。決してコードにリンクしてはいけません。*確かに*コードの写真にリンクしないでください。 – Carcigenicate

+3

あなたのコードを投稿してください。その写真へのリンクではありません。 – Bergi

+2

[**よく質問する方法**](https://stackoverflow.com/help/how-to-ask)と[**最小限で完全で検証可能なサンプルを作成する方法**]をご覧ください](https://stackoverflow.com/help/mcve) – Nope

答えて

2

グローバル関数の宣言は、そのconfigurableフラグfalseであるグローバルオブジェクト(ブラウザ上のウィンドウ)で結合を作成するため。これはGlobalDeclarationInstantiationに記載されています。CreateGlobalVarBindingを使用して関数のバインディングを作成し、Dフラグとしてfalseを渡します。これはconfigurableフラグに使用されます。 (これは、ステップ18.aに、関数名がFunctionDeclarationのある一つがHoistableDeclaration Sを含み、VarScopedDeclarations、を介して取得されvarDeclarationsから来るdeclaredVarNames、の一部であるです。)

結合は設定ないのでenumerableフラグをtrueからfalseに変更することはできません。

+0

しかし、なぜですか?なぜグローバルオブジェクト内の関数を削除することはできませんが、それらをundefinedにオーバーライドしますか? –

+3

@Jonasw:あなたはBrendan Eichに尋ねなければならないでしょうが、関数宣言は効果的に 'var'宣言と同じだと思うのですが、もちろんそれらの値がすぐに値を持ち、それが意味をなさない、帰ってきたとき)、あなたはそれらの本質的な特性を変えるでしょう。しかし、それは推測だ。 –

+1

これは答えの隠された宝石の1つです。細部までこだわり、仕様にまっすぐ進む。このような偉大な答えをありがとう。 –

1

グローバルスコープで関数を宣言すると、それはすでにwindowオブジェクトに配置され、設定可能フラグはfalseになります。これを回避する1つの方法は、別の関数の内部で関数を定義することであるので、同様に(生命維持は素晴らしい作品):

あなたはまた、あたりなどundefinedにそうでない場合、値のデフォルトをObject.defineProperties()内部propsオブジェクトのvalueプロパティを設定する必要がありますドキュメント。

(function() { 
 
    'use strict'; 
 
    function isBoolean() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "boolean") { 
 
     return true; 
 
    } else { 
 
     return false; 
 
    } 
 
    } 
 

 
    function isString() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "string") { 
 
     return true; 
 
    } else { 
 
     return false; 
 
    } 
 
    } 
 

 
    function isNumber() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (onoff) { 
 
     if (value === Infinity) { return Infinity; } 
 
    } 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "number") { 
 
     return true; 
 
    } else { 
 
     return false; 
 
    } 
 
    } 
 

 
    function isArray() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    return Array.isArray(value); 
 
    } 
 

 
    Object.defineProperties(window, { 
 
    "isBoolean": { enumerable: false, value: isBoolean }, 
 
    "isString" : { enumerable: false, value: isString }, 
 
    "isNumber" : { enumerable: false, value: isNumber }, 
 
    "isArray" : { enumerable: false, value: isArray }, 
 
    }); 
 
})();

1

、あなたの質問にecmascript-6タグを入れているので、私はあなたが関数式でletconstを使用することを示唆するかもしれませんか?関数文/宣言(大雑把にはvarのように振る舞う)とは異なり、let/constで宣言されたグローバル変数/定数は、グローバルオブジェクト(ここではwindow)のプロパティにはなりません。ここで直接テキストとして

const isBoolean = function() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "boolean") { 
 
    return true; 
 
    } else { 
 
    return false; 
 
    } 
 
}; 
 

 
const isString = function() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "string") { 
 
    return true; 
 
    } else { 
 
    return false; 
 
    } 
 
}; 
 

 
const isNumber = function() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    if (onoff) { 
 
    if (value === Infinity) { return Infinity; } 
 
    } 
 
    if (value===undefined || value===null) { return false; } 
 
    if (typeof(value) === "number") { 
 
    return true; 
 
    } else { 
 
    return false; 
 
    } 
 
}; 
 

 
const isArray = function() { 
 
    var value = arguments[0]; 
 
    if (!arguments.length) {return;} 
 
    return Array.isArray(value); 
 
}; 
 

 
console.log('"window" properties before "defineProperties":'); 
 
console.log('isBoolean: ' + ("isBoolean" in window)); 
 
console.log('isString: ' + ("isString" in window)); 
 
console.log('isNumber: ' + ("isNumber" in window)); 
 
console.log('isArray: ' + ("isArray" in window)); 
 

 
Object.defineProperties(window, { 
 
    "isBoolean": { enumerable: false }, 
 
    "isString" : { enumerable: false }, 
 
    "isNumber" : { enumerable: false }, 
 
    "isArray" : { enumerable: false }, 
 
}); 
 

 
console.log('"window" properties after "defineProperties":'); 
 
console.log('isBoolean: ' + ("isBoolean" in window)); 
 
console.log('isString: ' + ("isString" in window)); 
 
console.log('isNumber: ' + ("isNumber" in window)); 
 
console.log('isArray: ' + ("isArray" in window));

関連する問題