通过include()更改Leaflet类的行为

时间:2016-11-15 08:17:20

标签: javascript leaflet

您可以按including a mixin更改Leaflet.js类的行为。

教程Extending Leaflet: Class Theory说:

  

如果已定义类,则可以重新定义现有属性/方法,或者可以使用.include()添加新属性/方法:

但是,在尝试执行此操作时,我收到Maximum call stack size exceeded错误。

var DemoClass = L.Class.extend({
  value: 42,
  demoMethod: function() {
    return this.value;
  }
});

DemoClass.include({
  demoMethod: function() {
    return DemoClass.prototype.demoMethod.call(this) * 2;
  },
  secondMethod: function() {
    return this.value;
  }
});

var instance = new DemoClass();
console.log("value=" + instance.value);
console.log("secondMethod()=" + instance.secondMethod());
console.log("demoMethod()=" + instance.demoMethod()); // gives a call stack exceeded
<script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>

如果相关,则实际代码会覆盖L.Marker.onAdd()

2 个答案:

答案 0 :(得分:3)

  demoMethod: function() {
    return DemoClass.prototype.demoMethod.call(this) * 2;
  },

你正在那里进行无限递归通话。

JS有时很奇怪,这次就是其中之一。引用DemoClass.prototype,您指的是DemoClass.prototype最新状态 ...因此DemoClass.prototype.demoMethod指的是本身

每当您覆盖原型方法或属性时,前一个方法或属性都会获得de-referenced and potentially garbage-collected

如果您想参考以前的方法定义,您必须保留对方法的先前定义的引用

这通常需要JS closure形式的一些技巧(在某些受控变量范围内保持对原始值的引用)。有多种方法可以做到这一点:保持对前一个原型的引用作为类属性,就像@Jaws一样;在某个地方做一个关闭;像IIFE中那样做Leaflet.GridLayer.FadeOut,或者让你保留对原始方法定义的引用。

答案 1 :(得分:1)

尝试隔离基本功能:

var DemoClass = L.Class.extend({
  value: 42,
  demoMethod: function() {
    return this.value;
  }
});

DemoClass.include({
  baseDemoMethod: DemoClass.prototype.demoMethod,
  demoMethod: function() {
    return this.baseDemoMethod() * 2;
  },
  secondMethod: function() {
    return this.value;
  }
});

var instance = new DemoClass();
console.log("value=" + instance.value);
console.log("secondMethod()=" + instance.secondMethod());
console.log("demoMethod()=" + instance.demoMethod());
<script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>