2017-05-18 3 views
-8

Wenn ich den folgenden Code ausführen, erhalte ich die Fehlermeldung:Warum kann Eigentum nicht neu definiert werden?

TypeError: Cannot redefine property: isBoolean

Warum kann ich diese Eigenschaften nicht neu definieren?

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

Beitrag aller Code hier direkt als Text. Verknüpfen Sie niemals mit Code und * sicherlich * niemals mit Code-Bildern. – Carcigenicate

+3

Bitte poste deinen Code, keinen Link zu einem Bild davon. – Bergi

+2

Siehe [** Wie stelle ich eine gute Frage? **] (https://stackoverflow.com/help/how-to-ask) und [** Wie erstelle ich ein minimales, vollständiges und verifizierbares Beispiel ** ] (https://stackoverflow.com/help/mcve) – Nope

Antwort

2

Da eine globale Funktionsdeklaration schafft auf das globale Objekt eine Bindung (das Fenster, auf Browsern), deren configurable Flag false ist. Dies wird in GlobalDeclarationInstantiation behandelt, die CreateGlobalVarBinding verwendet, um die Bindung für die Funktion zu erstellen, wobei false als das -Flag übergeben wird, das für das Flag configurable verwendet wird. (Es ist in Schritt 18.a, Funktionsnamen Teil des declaredVarNames sind, die sich von varDeclarations kommen, die über VarScopedDeclarations abgerufen werden, welche HoistableDeclaration s umfasst, von denen eine FunctionDeclaration ist.)

Da die Bindung nicht konfigurierbar ist, Sie können das enumerable Flag von true zu false nicht ändern.

+0

Aber warum? Warum können wir Funktionen im globalen Objekt nicht löschen, sondern sie in undefined überschreiben? –

+3

@Jonasw: Sie müssten Brendan Eich fragen, aber ich denke, das liegt daran, dass Funktionsdeklarationen praktisch die gleichen wie 'var' Deklarationen sind, außer natürlich haben sie sofort ihren Wert und es ergab keinen Sinn (für ihn , als du zurück warst), dass du ihre wesentlichen Eigenschaften ändern würdest. Aber das ist Spekulation. –

+1

Dies ist einer dieser versteckten Schätze einer Antwort. So detailliert und direkt zu den Spezifikationen. Danke für die tolle Antwort. –

1

Das Problem ist, dass, wenn Sie eine Funktion auf dem globalen Bereich erklären, es stellt sie bereits auf das window Objekt mit dem konfigurierbaren Flag gleich falsch. Eine Möglichkeit, dies zu vermeiden, ist es, die Funktionen innerhalb einer anderen Funktion zu definieren (ein IIFE funktioniert gut) wie folgt:

Sie sollten auch die value Eigenschaft des props Objekt innerhalb Object.defineProperties() werden Einstellung, andernfalls wird der Wert standardmäßig undefined per die Dokumente.

(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

Da Sie die ecmascript-6 Tag in Frage stellen, kann ich schlage vor, Sie let oder const mit Funktionsausdrücke zu benutzen? Im Gegensatz zu einer Funktionsanweisung/Deklaration (die sich grob wie var verhält) werden globale Variablen/Konstanten, die mit let/const deklariert sind, keine Eigenschaften des globalen Objekts (hier 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));

Verwandte Themen