简体   繁体   中英

How to turn this object to dot-notation?, so I can call multiple methods on a single line

I'm quite new to OOP and still learning new techniques every time, and this is one of my tasks that I tend to do as daily basis for learning better...

Anyway, back to question; basically I've this app object of which I'd like to turn it into dot-notation when calling methods...

var app = function() {

    var DEFAULTS = {
        websiteName: 'Stylish App',
        websiteUrl: 'http://stylishapp.ltd',
        websiteCopyright: 'Copyright ' + new Date().getFullYear() + ' ' + this.websiteName + '.',
        websiteLanguage: 'English'
    }

    var output;

    return {

        name: function() {
            return DEFAULTS.websiteName;
        },
        url: function() {
            return DEFAULTS.websiteUrl;
        },
        copyright : function() {
            return DEFAULTS.websiteCopyright;
        }

    }
}();
  1. So I want to be able to call my methods one after the other like so;

     document.write( app.websiteName().websiteUrl() ); 

    I know it wouldn't make sense to use for this example as nobody prints their website name followed by the url, but it's an example anyway...

  2. Also in my DEFAULTS object, I tried to referring back to the actual websiteName as for the value of websiteCopyright ... but I get an error saying websiteName undefined, also tried this.websiteName as well as DEFAULTS.websiteName , but none of them actually worked!

Hope it makes sense to what I'm looking to achieve Thanks in advance :)

Seeing as you're encapsulating your functionality in the module pattern anyway, those defaults could just be private variables, at which point you can just refer to other variables directly

 var app = function() { var name = 'Stylish App'; var url = 'http://stylishapp.ltd'; var copyright = 'Copyright ' + new Date().getFullYear() + ' ' + name + '.'; var language = 'English' return { name: function() { return name; }, url: function() { return url; }, copyright : function() { return copyright; } } }(); document.write(app.name()); document.write("<br>"); document.write(app.url()); document.write("<br>"); document.write(app.copyright()); 

As for the other question, regarding this sort of syntax

document.write(  app.websiteName().websiteUrl()  );

Thats generally refered to as a "fluent" interface (you refer to this as dot-notation , which is wrong), where each method call returns this so that the next method can be chained on.

As a convoluted example drawing on the above code:

 var app = function() { var name = 'Stylish App'; var url = 'http://stylishapp.ltd'; var copyright = 'Copyright ' + new Date().getFullYear() + ' ' + name + '.'; var language = 'English' return { writeName: function() { document.write(name + "<br>"); return this; }, writeUrl: function() { document.write(url + "<br>"); return this; }, writeCopyright : function() { document.write(copyright + "<br>"); return this; } } }(); app.writeName().writeCopyright(); 

I really wouldn't recommend doing this. You are trying to get strings, not manipulate an object. jQuery doesn't do this when you are doing something like $('body').attr('class'); . It just returns a string.

That said, you can:

  1. Return a new instance of the object (so that you avoid mutating the existing one)
  2. Special case conversion to a string

Such:

 function App(defaults, string) { defaults = defaults || {}; this.string = string || ""; this.websiteName = defaults.websiteName || 'Stylish App'; this.websiteUrl = defaults.websiteUrl || 'http://stylishapp.ltd'; this.websiteCopyright = this.websiteCopyright || 'Copyright ' + new Date().getFullYear() + ' ' + this.websiteName + '.'; this.websiteLanguage = defaults.websiteLanguage || 'English'; } App.prototype.toString = function toString() { return this.string; } App.prototype.name = function name() { var string = this.string; if (string) { string += " "; } string += this.websiteName; return new App(this, string); } App.prototype.url = function url() { var string = this.string; if (string) { string += " "; } string += this.websiteUrl; return new App(this, string); } App.prototype.copyright = function copyright() { var string = this.string; if (string) { string += " "; } string += this.websiteCopyright; return new App(this, string); } var app = new App(); alert(app.name().copyright()); 

So, if a method is supposed to return something specific, then chaining would not apply to that method. Other methods that "do something" and are not expected to return anything would return this . Here's an example:

 function Person (name) { this.getName = function (){ return name; } //no chaining this.setName = function (newName) { //chaining! name = newName; return this; } this.alertName = function () { //chaining alert(name); return this; } } var dad = new Person ('Bob'); dad.setName('Bob').alertName(); //we can chain here because "this" was returned in setName method 

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