namespace MyApplication:Some: class Any # window.MyApplication.Some.Any namespace global: class Some # window.Some
namespace
function and send {MyApplication:{Some: _}}
object there {MyApplication:{Some: _}}
window.namespace = -> args = arguments[0] target = global || window loop for subpackage, obj of args target = target[subpackage] or= {} args = obj break unless typeof args is 'object' Class = args target = window if arguments[0].hasOwnProperty 'global' name = if !Class.name? # IE Fix args.toString().match(/^function\s(\w+)\(/)[1] else Class.name proto = target[name] or undefined target[name] = Class if proto? for i of proto target[name][i] = proto[i]
using
, use
, import
, but alas - you can only implement these at the level of the preprocessor itself, but not at all at the language level. But in the case of CoffeeScript, it turns out that there are some properties of the language itself that make it possible to realize import almost beautifully: {Any} = MyApplication.Some # MyApplication.Some.Any Any {Any: Test} = MyApplication.Some # MyApplication.Some.Any Test
use
in php: use MyApplication\Some\Any; use MyApplication\Some\Any as Test;
class Some @MY_DEFINE = 42 @getVar: -> @MY_DEFINE getVar: -> @contructor.MY_DEFINE # Some.MY_DEFINE
Some.MY_DEFINE
__defineGetter__
and similar constructs for creating getters will only complicate reading. class Some MY_DEFINE = 42 @getVar: -> MY_DEFINE getVar: -> MY_DEFINE
const MY_DEFINE = 42
in reverse single quotes (where the letter is “E”), or adding functions to the Function
prototype that will register constants with getters / setters, but these are not very popular techniques, so I’m I'll keep them silent and better offer my version (a bit more close to reality): class Ajax define AJAX_UNSENT: 0 define AJAX_OPENED: 1 define AJAX_HEADERS_RECEIVED: 2 define AJAX_LOADING: 3 define AJAX_READY: 4 request: -> # if xhr.status is AJAX_READY # -
window.define = (args) -> for name, val of args continue if window[name]? do (name, val) -> unless window.__defineGetter__? # IE Fix return window[name] = val window.__defineGetter__ name, -> val window.__defineSetter__ name, -> throw new Error "Can not redeclare define #{name}. Define already exists." # window.defined = (name) -> return window.__lookupGetter__(name)? && window[name]?
window
, which will return the desired value and the setter, which blocks the possibility of rewriting the constant.window
- globals were never a good solution, but I do not think that this is so significant in the light of possible gains in readability and convenience of the code, and the problems of collisions are solved with the usual prefixes. class Some test = $private 'test' constructor: -> @[test] = 23 console.log(new Some)
var
test
variable, the value of which will be the string [private test]
(returned by the function $ private). Next, we simply use this variable as the name for our real variable. And since our name begins with an invisible character, access to a variable is rather difficult to obtain, especially if the prefix is ​​generated from random invisible characters. window.$private = (name) -> unless defined 'ZERO_WIDTH_SPACE' define ZERO_WIDTH_SPACE: '​' # , return "#{ZERO_WIDTH_SPACE}[private #{name}]"
nameof [] # 'Array' nameof {} # 'Object' nameof SomeClass # 'SomeClass'
window.nameof = (cls) -> if typeof cls is 'object' cls = cls.constructor else if typeof cls isnt 'function' return typeof cls name = unless cls.name? cls.toString().match(/function\s(\w+)\(/)[1] else cls.name return name
class Some abstractMethod: abstract class Any extends Some (new Any).abstractMethod() # Error 'Can not call abstract method' # class Any2 extends Some abstractMethod: -> console.log 42 (new Any).abstractMethod() # 42
window.abstract = -> throw new Error 'Can not call abstract method'
Source: https://habr.com/ru/post/235205/
All Articles