Ember.js reopenClass是如何工作的?

Koe*_*ers 24 ember.js

我真的没有得到ember.js'reopenClass的功能.我认为它为Object的原型添加了额外的代码,因此该Object的所有实例都将获得以非静态方式添加的功能.但是,它没有这样做.看起来它只添加了可以静态执行的代码.例如.我有这个代码:

Logger = Ember.Object.extend({ 
  log: function(thing) { 
     console.log(thing + ' wassup'); 
    }
});

var logger = Logger.create();
logger.log("1, yo")

logger.reopen({ 
  log: function(name) { 
      console.log(name + 'ghurt')
    }
});
logger.log("2, yo")

Logger.reopenClass({ 
  log: function(name) { 
      console.log(name + 'fresh')
    }
});
logger.log("3, yo")
Logger.log("4, yo")
Run Code Online (Sandbox Code Playgroud)

它输出这个:

1, yo wassup
2, yoghurt
3, yoghurt
4, yofresh
Run Code Online (Sandbox Code Playgroud)

我的期望是这样的:

1, yo wassup
2, yoghurt
3, yofresh
4, undefined (I think)
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:reopenClass做什么以及何时使用它?

pan*_*atz 45

一般情况下,reopen增加了方法和属性来实例,而reopenClass增加了方法和属性来的类.

相应的测试是ember-runtime/tests/system/object/reopen_test.jspackages/ember-runtime/tests/system/object/reopenClass_test.js.

我已更新您的代码并添加了一些注释,请参阅http://jsfiddle.net/pangratz666/yWKBF/:

Logger = Ember.Object.extend({
    log: function(thing) {
        console.log(thing + ' wassup');
    }
});

var logger1 = Logger.create();
var logger2 = Logger.create();

// instances of Logger have a 'wassup' method
try { Logger.log("1, yo"); } catch (e) {} // Object (subclass of Ember.Object) has no method 'log'
logger1.log("1, yo"); // 1, yo wassup
logger2.log("1, yo"); // 1, yo wassup

console.log('----');

// overwrite log of concrete logger instance logger1
logger1.reopen({
    log: function(name) {
        console.log(name + ' ghurt');
    }
});

try { Logger.log("1, yo"); } catch (e) {} // Object (subclass of Ember.Object) has no method 'log'
logger1.log("2, yo"); // 2, yo ghurt
logger2.log("2, yo"); // 2, yo wassup

console.log('----');

// classes of Logger have a 'fresh' method
Logger.reopenClass({
    log: function(name) {
        console.log(name + ' fresh');
    }
});

Logger.log("3, yo"); // 3, yo fresh
logger1.log("3, yo"); // 3, yo ghurt
logger2.log("3, yo"); // 3, yo wassup

console.log('----');

// new* instances of Logger have from now on a 'dawg' method
// * this will likely change in the future so already existing instances will reopened too
Logger.reopen({
    log: function(name) {
        console.log(name + ' dawg');
    }
});

Logger.log("4, yo"); // 4, yo fresh
logger1.log("4, yo"); // 4, yo ghurt
logger2.log("4, yo"); // 4, yo wassup
Logger.create().log("4, yo"); // 4, yo dawg

console.log('----');
Run Code Online (Sandbox Code Playgroud)

  • 好的,所以如果我得到这个权利logger.reopen()只将代码添加到记录器实例,Logger.reopen()为每个将要创建的新实例(现有实例不会更改)和Logger.reopenClass( )向Logger类添加静态代码(不能从实例调用,只能静态调用).正确? (9认同)
  • @koenp - fyi,我在博客上写了关于Ember.Object的内容,包括课程与实例,混合等等 - http://www.cerebris.com/blog/2012/03/06/understanding-ember-object/ (5认同)
  • 好.谢谢你的光线.我很难从http://emberjs.com/documentation/上的文档中了解这一点(如:我没有得到它)​​. (2认同)