Πώς μπορώ δυναμικά ορίσετε ιδιότητες σε ένα αντικείμενο με γραφομηχανή;

ψήφοι
129

Αν ήθελα να εκχωρήσετε κάποιου προγράμματος ένα ακίνητο σε ένα αντικείμενο σε Javascript, θα έκανα αρέσει αυτό:

var obj = {};
obj.prop = value;

Αλλά στη γραφομηχανή, αυτό δημιουργεί ένα σφάλμα:

Το ακίνητο «prop» δεν υπάρχει σχετικά με την αξία του τύπου «{}»

Πώς πρέπει να εκχωρήσετε κάθε νέο ακίνητο σε ένα αντικείμενο με γραφομηχανή;

Δημοσιεύθηκε 03/10/2012 στις 15:42
πηγή χρήστη
Σε άλλες γλώσσες...                            


21 απαντήσεις

ψήφοι
111

Είναι δυνατόν να υποδηλώσει objόπως any, αλλά νικά ολόκληρο το σκοπό της χρήσης γραφομηχανή. obj = {}υπονοεί objείναι ένα Object. Επισήμανση ως anyέχει κανένα νόημα. Για να επιτευχθεί η επιθυμητή συνεκτικότητα μια διασύνδεση θα μπορούσε να οριστεί ως εξής.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

Ή για να γίνει συμπαγής:

var obj: {[k: string]: any} = {};

LooseObjectμπορεί να δεχθεί τα πεδία με οποιαδήποτε συμβολοσειρά ως κλειδί και anyπληκτρολογήστε ως τιμή.

obj.prop = "value";
obj.prop2 = 88;

Η πραγματική κομψότητα της λύσης αυτής είναι ότι μπορείτε να συμπεριλάβετε typesafe πεδία στο περιβάλλον.

interface MyType {
    typesafeProp1?: number,
    requiredProp1: string,
    [key: string]: any
}

var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number

obj.prop = "value";
obj.prop2 = 88;
Απαντήθηκε 08/06/2017 στις 16:32
πηγή χρήστη

ψήφοι
61

Ή σε μία μόνο στιγμή:

  var obj:any = {}
  obj.prop = 5;
Απαντήθηκε 03/10/2012 στις 16:51
πηγή χρήστη

ψήφοι
45

Τείνω να θέσει anyαπό την άλλη πλευρά, δηλαδή var foo:IFoo = <any>{};λοιπόν κάτι τέτοιο είναι ακόμα typesafe:

interface IFoo{
    bar:string;
    baz:string;
    boo:string;     
}

// How I tend to intialize 
var foo:IFoo = <any>{};

foo.bar = "asdf";
foo.baz = "boo";
foo.boo = "boo";

// the following is an error, 
// so you haven't lost type safety
foo.bar = 123; 

Εναλλακτικά, μπορείτε να επιλέξετε αυτές τις ιδιότητες ως προαιρετικό:

interface IFoo{
    bar?:string;
    baz?:string;
    boo?:string;    
}

// Now your simple initialization works
var foo:IFoo = {};

Δοκιμάστε το σε απευθείας σύνδεση

Απαντήθηκε 26/08/2013 στις 13:32
πηγή χρήστη

ψήφοι
24

Η λύση αυτή είναι χρήσιμη όταν το αντικείμενό σας έχει συγκεκριμένο τύπο. Όπως και κατά την απόκτηση του αντικειμένου σε άλλη πηγή.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Απαντήθηκε 25/08/2016 στις 08:51
πηγή χρήστη

ψήφοι
21

Παρά το γεγονός ότι ο compiler παραπονιέται ακόμα θα έπρεπε εξόδου ως χρειάζεστε. Ωστόσο, αυτό θα λειτουργήσει.

var s = {};
s['prop'] = true;
Απαντήθηκε 03/10/2012 στις 15:57
πηγή χρήστη

ψήφοι
14

Μία ακόμη επιλογή να κάνει με αυτό είναι να έχει πρόσβαση το ακίνητο ως μια συλλογή:

var obj = {};
obj['prop'] = "value";

Απαντήθηκε 22/03/2017 στις 13:23
πηγή χρήστη

ψήφοι
4

Για να διασφαλιστεί ότι ο τύπος είναι ένα Object(δηλαδή ζεύγη κλειδιών-τιμών ), χρησιμοποιήστε:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Απαντήθηκε 16/06/2017 στις 14:15
πηγή χρήστη

ψήφοι
3

Η καλύτερη πρακτική είναι να χρησιμοποιήσετε την ασφαλή πληκτρολόγηση, σας προτείνουμε:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Απαντήθηκε 11/10/2016 στις 23:32
πηγή χρήστη

ψήφοι
2
  • Περίπτωση 1:

    var car = {type: "BMW", model: "i8", color: "white"}; car['owner'] = "ibrahim"; // You can add a property:

  • Περίπτωση 2:

    var car:any = {type: "BMW", model: "i8", color: "white"}; car.owner = "ibrahim"; // You can set a property: use any type

Απαντήθηκε 12/01/2019 στις 15:45
πηγή χρήστη

ψήφοι
2

Για να διατηρήσετε τα προηγούμενα τύπο, την προσωρινή χυτό αντικείμενο σας για οποιαδήποτε

  var obj = {}
  (<any>obj).prop = 5;

Η νέα δυναμική ακινήτων θα είναι διαθέσιμη μόνο όταν χρησιμοποιείτε το καστ:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Απαντήθηκε 09/12/2016 στις 16:44
πηγή χρήστη

ψήφοι
2

Αποθηκεύστε κάθε νέο ακίνητο σε κάθε είδους αντικειμένου από typecasting να «κάθε»:

var extend = <any>myObject;
extend.NewProperty = anotherObject;

Αργότερα μπορείτε να ανακτήσετε από χύτευση όλο το αντικείμενό σας πίσω σε «κάθε»:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Απαντήθηκε 25/11/2015 στις 13:21
πηγή χρήστη

ψήφοι
2

Μπορείτε να προσθέσετε αυτή τη δήλωση για να φιμώσουν τις προειδοποιήσεις.

declare var obj: any;

Απαντήθηκε 03/10/2012 στις 16:02
πηγή χρήστη

ψήφοι
1

Είμαι έκπληκτος ότι καμία από τις απαντήσεις αναφοράς Object.assign δεδομένου ότι είναι η τεχνική που χρησιμοποιώ όποτε σκέφτομαι «σύνθεση» σε JavaScript.

Και αυτό λειτουργεί όπως αναμένεται με τυπογραφικούς χαρακτήρες:

interface IExisting {
    userName: string
}

interface INewStuff {
    email: string
}

const existingObject: IExisting = {
    userName: "jsmith"
}

const objectWithAllProps: IExisting & INewStuff = Object.assign({}, existingObject, {
    email: "jsmith@someplace.com"
})

console.log(objectWithAllProps.email); // jsmith@someplace.com

Πλεονεκτήματα

  • πληκτρολογήστε την ασφάλεια σε ολόκληρη γιατί δεν χρειάζεται να χρησιμοποιήσετε τον anyτύπο σε όλα
  • χρησιμοποιεί συγκεντρωτικά τύπου γραφομηχανή (όπως υποδηλώνεται από το &όταν δηλώνει το είδος του objectWithAllProps), το οποίο επικοινωνεί με σαφήνεια ότι είμαστε σύνθεση ενός νέου τύπου on-the-fly (δηλαδή δυναμικά)

Πράγματα που πρέπει να γνωρίζει

  1. Object.assign έχει το δικό του μοναδικό πτυχές (που είναι γνωστές σε πιο έμπειρους προγραμματιστές JS) που θα πρέπει να λαμβάνονται υπόψη κατά τη σύνταξη γραφομηχανή.
    • Μπορεί να χρησιμοποιηθεί σε ένα μεταβλητό τρόπο, ή ένα αμετάβλητο τρόπο (Ι αποδεικνύουν την αμετάβλητο τρόπο παραπάνω, πράγμα που σημαίνει ότι existingObjectπαραμένει ανέγγιχτη και ως εκ τούτου δεν έχει emailπεριουσία. Για τους περισσότερους προγραμματιστές λειτουργικό στιλ, αυτό είναι ένα καλό πράγμα δεδομένου ότι το αποτέλεσμα είναι η μόνη νέα αλλαγή).
    • Object.assign λειτουργεί το καλύτερο όταν έχεις πιο επίπεδη αντικείμενα. Εάν ο συνδυασμός δύο ένθετα αντικείμενα που περιέχουν nullable ιδιότητες, μπορείτε να καταλήξετε αντικατάσταση truthy τιμές με απροσδιόριστη. Αν προσέξετε την σειρά των Object.assign επιχειρήματα, θα πρέπει να είναι μια χαρά.
Απαντήθηκε 30/01/2019 στις 16:21
πηγή χρήστη

ψήφοι
1

Είναι δυνατόν να προσθέσετε ένα μέλος σε ένα υπάρχον αντικείμενο από

  1. τη διεύρυνση του τύπου (διαβάστε: επεκτείνει / ειδικεύονται τη διεπαφή)
  2. ρίχνει το αρχικό αντικείμενο την εκτεταμένη τύπου
  3. προσθέστε το μέλος με το αντικείμενο
interface IEnhancedPromise<T> extends Promise<T> {
    sayHello(): void;
}

const p = Promise.resolve("Peter");

const enhancedPromise = p as IEnhancedPromise<string>;

enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value));

// eventually prints "Hello Peter"
enhancedPromise.sayHello();
Απαντήθηκε 08/03/2018 στις 11:20
πηγή χρήστη

ψήφοι
1

Εάν χρησιμοποιείτε γραφομηχανή, προφανώς θέλετε να χρησιμοποιήσετε την ασφάλεια τύπο? στην οποία περίπτωση γυμνή αντικειμένων και «κάθε» Οι αντενδείξεις.

Καλύτερα να μην χρησιμοποιούν Object ή {}, αλλά κάποιο που ονομάζεται τύπου? ή ίσως να χρησιμοποιείτε ένα API με συγκεκριμένους τύπους, το οποίο θα πρέπει να επεκτείνει με δικά σας πεδία. Έχω διαπιστώσει ότι αυτό το έργο:

class Given { ... }  // API specified fields; or maybe it's just Object {}

interface PropAble extends Given {
    props?: string;  // you can cast any Given to this and set .props
    // '?' indicates that the field is optional
}
let g:Given = getTheGivenObject();
(g as PropAble).props = "value for my new field";

// to avoid constantly casting: 
let k:PropAble = getTheGivenObject();
k.props = "value for props";
Απαντήθηκε 02/01/2018 στις 03:07
πηγή χρήστη

ψήφοι
1

δυναμικά εκχωρήσει ιδιότητες σε ένα αντικείμενο στη γραφομηχανή.

Για να γίνει αυτό απλά πρέπει να χρησιμοποιήσει τις διασυνδέσεις γραφομηχανή όπως έτσι:

interface IValue {
    prop1: string;
    prop2: string;
}

interface IType {
    [code: string]: IValue;
}

μπορείτε να το χρησιμοποιήσετε σαν αυτό

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Απαντήθηκε 30/03/2017 στις 04:31
πηγή χρήστη

ψήφοι
0

μπορείτε να χρησιμοποιήσετε αυτό:

this.model = Object.assign(this.model, { newProp: 0 });
Απαντήθηκε 09/07/2019 στις 23:53
πηγή χρήστη

ψήφοι
0

Μπορείτε να δημιουργήσετε νέο αντικείμενο με βάση το παλαιό αντικείμενο χρησιμοποιώντας τον τελεστή εξάπλωση

interface MyObject {
    prop1: string;
}

const myObj: MyObject = {
    prop1: 'foo',
}

const newObj = {
    ...myObj,
    prop2: 'bar',
}

console.log(newObj.prop2); // 'bar'

Γραφομηχανή, θα συμπεράνουμε όλα τα πεδία του αρχικού αντικειμένου και VSCode θα κάνει αυτόματη συμπλήρωση, κ.λπ.

Απαντήθηκε 10/06/2019 στις 01:59
πηγή χρήστη

ψήφοι
0

Απλούστερη θα ακόλουθη

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Απαντήθηκε 02/05/2019 στις 23:18
πηγή χρήστη

ψήφοι
0

javascript:

myObj.myProperty = 1;

γραφομηχανή:

myObj['myProperty'] = 1;
Απαντήθηκε 09/02/2019 στις 09:43
πηγή χρήστη

ψήφοι
-1

Αν είστε σε θέση να χρησιμοποιήσετε τις λειτουργίες ES6 JavaScript, μπορείτε να χρησιμοποιήσετε υπολογιστικής ονόματα ιδιοτήτων για να χειριστεί αυτό πολύ εύκολα:

var req = {id : 0123456};    
var response = {responses: {[req.id]: 'The 0123456 response message'}};

Το [req.id] βασικό αντικείμενο έχει μια δυναμική τιμή

Απαντήθηκε 16/01/2018 στις 11:03
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more