从构造函数实例化的类范围对象

时间:2014-10-03 00:12:41

标签: javascript oop design-patterns meteor coffeescript

在下面的someAPI中,它需要我想在构造函数中动态分配的凭据。然后我想在整个课程中使用someAPI。即在下面的例子中,someMethodUsingSomeAPI是一个帮助器方法,我想从B实例中的其他方法调用。这可能与Coffee- / JavaScript有关吗? (我可以让它工作的唯一方法是在构造函数中放入someMethodUsingSomeAPI。)

SomeAPI = Npm.require 'someAPI'

class B extends A
  constructor: (options = {}) ->
    unless @ instanceof B
      return new B(options)

    @config = JSON.parse(Assets.getText('config/' + options.username + '.json'))

    @someAPI = new SomeAPI
      consumer_key: @config.credentials.consumer.key
      consumer_secret: @config.credentials.consumer.secret
      access_token: @config.credentials.access.token
      access_token_secret: @config.credentials.access.secret

  someMethodUsingSomeAPI = Async.wrap((id, callback) ->
    return @someAPI.get 'whatever/show', { 'id': id }, callback
  )

  console.log someMethodUsingSomeAPI '123' # Error: Cannot call method 'get' of undefined

更新了saimeunt的建议

...

someMethodUsingSomeAPI = (id) ->
  wrappedGet = Async.wrap(@someAPI, 'get')
  wrappedGet 'whatever/show', { id: id }

console.log someMethodUsingSomeAPI '123' # ReferenceError: someMethodUsingSomeAPI is not defined

&安培;

b = B('username')
b.someMethodUsingSomeAPI '123' # Works!

someMethodUsingSomeAPI:更改为someMethodUsingSomeAPI =

console.log someMethodUsingSomeAPI '123' # Error: unsupported argument list

&安培;

b = B('username')
b.someMethodUsingSomeAPI '123' # TypeError: Object #<B> has no method 'someMethodUsingSomeAPI'

(这是Meteor 0.9.3.1)

在尝试澄清时更新

Here's a simplified version of the above, without any of the API stuff.

someMethod = workssomeMethod: doesn't work

我很高兴classInstance.someMethod在使用时很有效:但是真的很想让它在实际的实例中运行。

3 个答案:

答案 0 :(得分:0)

当然,您可以将someAPI附加到您的类对象上。在coffeescript中@代替this(就像在Javscript中一样)。

SomeAPI = require 'someAPI'

class A extends B
  constructor: (options = {}) ->
    unless @ instanceof A
      return new A(options)

    @config = JSON.parse('config/' + options.username + '.json')

    @someAPI = new SomeAPI
      consumer_key: @config.credentials.consumer.key
      consumer_secret: @config.credentials.consumer.secret
      access_token: @config.credentials.access.token
      access_token_secret: @config.credentials.access.secret

  someMethodUsingSomeAPI:  (id, callback) ->
    return @someAPI.get 'whatever/show', { 'id': id }, callback

您可以查看解释Javascript this的{​​{3}}及其范围。理解了这一点后,请查看this SO question的工作原理,并且您应该清楚@的使用。

答案 1 :(得分:0)

我认为这就是你想要的:

someMethodUsingSomeAPI:function(id){
  var wrappedGet=Async.wrap(@someAPI,"get");
  return wrappedGet("whatever/show",{
    id:id
  });
}

答案 2 :(得分:0)

根据您在此处提供的简化示例,该版本应符合您的要求:

class SomeClass
  # Store the last created instance at the class level
  lastInstance: null

  constructor: (options = {}) ->
    @someLastName = options.someLastName 
    # In constructor, the created instance is now the lastInstance
    SomeClass.lastInstance = this

# The helper method is not created in the class scope
someMethod = (someFirstName) ->
  "Hello " + someFirstName + " " + SomeClass.lastInstance.someLastName

someClass = new SomeClass({ someLastName: 'Borgnine' })

alert someMethod 'Ernest'

here's a link to try it in a browser

基本上,正如您希望助手方法访问类的实例一样,您需要提供对助手可以在某个时刻引用的该实例的引用。这里我使用一个类变量来存储最后创建的实例,以及调用时最后一个实例的帮助器访问。这意味着在创建许多实例时,它将执行如下操作:

someClass = new SomeClass({ someLastName: 'Borgnine' })

alert someMethod 'Ernest' # Hello Ernest Borgnine

someClass = new SomeClass({ someLastName: 'Doe' })

alert someMethod 'Boris' # Hello Boris Doe