The Kai Way

Pragmaticly hacking

Instance Property of CoffeeScript

| Comments

用Class语法定义的Instance Property是直接append到prototype上,当 你把一个property定义为某个对象(非立即值)时,那所有的 Instance都会指向同一个内存地址上。

1
2
class Foo
  favSites: ["Google"]

会编译得到:

1
2
3
4
5
6
7
var Foo;

Foo = (function() {
  function Foo() {}
  Foo.prototype.favSites = ["Google"];
  return Foo;
})();

这里容易犯错的地方就是当有实例去修改上面提到的共享 内存地址的内容,这样就会得到一个奇怪的结果。

1
2
3
4
5
foo1 = new Foo
foo2 = new Foo

foo1.favSites.push "Github"
alert foo2.favSites # => ["Google", "Github"]

当不想出现这种情况时最好避免直接把Instance Property定义在 Class Contructor的prototype上。

1
2
3
4
5
6
7
8
9
class Foo
  constructor: (@options = {}) ->
    @favSites = ["Google"]

foo1 = new Foo
foo2 = new Foo

foo1.favSites.push "Github"
alert foo2.favSites # => ["Google"]

在Backbonejs里也是这么处理的,比如在Model中,每个实例的所 有属性值(attributes):

1
2
3
4
5
6
7
8
9
10
11
12
var Model = Backbone.Model = function(attributes, options) {
    var defaults;
    attributes || (attributes = {});
    #...
    this.attributes = {};
    this._escapedAttributes = {};
    this.cid = _.uniqueId('c');
    this.changed = {};
    this._silent = {};
    this._pending = {};
    #...
}

Comments