简体   繁体   中英

How to use properties of one object in another

I want to create my own class, lets say Data which will contain File and additional info about it:

Data = function(file, oneInfo, anotherInfo, moreInfo) { 
    this.file = file;
    this.property1 = oneInfo;
    this.property1 = anotherInfo;
    this.property1 = moreInfo;
};

But I would like to read info about file directly from my object Data, for example Data.size I can do it (ugly) like this:

Data = function(file, oneInfo, anotherInfo, moreInfo) { 
    this.file = file;
    this.size = file.size;
    this.property1 = oneInfo;
    this.property1 = anotherInfo;
    this.property1 = moreInfo;
};

so now Data.size is accessible, but is there any other way which i can use to call for file properties without Data.file.size or my ugly version? Maybe some kind of inherit properties from File to Data? Of course the File must be still accessible (for example for using it to send through xhr.send() )

so now Data.size is accessible

I'm going to assume you mean that if you do var d = new Data(...); , then d.size is accessible.

If so, you can do it (in ES5 and higher) by defining a property accessor via Object.defineProperty ( MDN | spec ):

Object.defineProperty(Data.prototype, "size", {
    // The "getter" is called when you _get_ the value
    // You don't have to define one, though it's odd if you don't
    get: function() {
        return this.file && this.file.size;
    },
    // The "setter" is called when you _set_ the value
    // You don't have to define one; if you don't the property is read-only
    set: function(value) {
        if (this.file) {
            this.file.size = value;
        }
    }
});

Live Example:

 function Data(file) { this.file = file; } Object.defineProperty(Data.prototype, "size", { // The "getter" is called when you _get_ the value // You don't have to define one, though it's odd if you don't get: function() { return this.file && this.file.size; }, // The "setter" is called when you _set_ the value // You don't have to define one; if you don't the property is read-only set: function(value) { if (this.file) { this.file.size = value; } } }); // Initial setup var f = { size: 10 }; var d = new Data(f); console.log(d.size); // 10 // Changing f.size affects what you get back from d.size f.size = 20; console.log(d.size); // 20 // Changing d.size changes f.size d.size = 30; console.log(f.size); // 30

Obsolete JavaScript engines like the one in IE8 won't be able to handle it, but all modern ones will.

In ES2015+, you can use class syntax with an accessor definition:

class Data {
    constructor(file) {
        this.file = file;
    }
    get size() {
        return this.file && this.file.size;
        // In ES2020+ you could use optional chaining:
        // return this.file?.size;
    }
    set size(value) {
        if (this.file) {
            this.file.size = value;
        }
    }
}

Live Example:

 class Data { constructor(file) { this.file = file; } get size() { return this.file && this.file.size; } set size(value) { if (this.file) { this.file.size = value; } } } // Initial setup const f = { size: 10 }; const d = new Data(f); console.log(d.size); // 10 // Changing f.size affects what you get back from d.size f.size = 20; console.log(d.size); // 20 // Changing d.size changes f.size d.size = 30; console.log(f.size); // 30

Might be a good use case for getter properties:

Object.defineProperty(Data.prototype, 'size', {
   get: function () {
       return this.file.size;
   }
});

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM