如何正确定义javascript原型绑定?

时间:2017-01-20 11:41:56

标签: javascript prototype-programming

你能帮我把这个函数绑定到var orbitElement; var targetRotation = 0; var targetRotationOnMouseDown = 0; var mouseX = 0; var mouseXOnMouseDown = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; var Controls = { enableOrbiting: function(target) { orbitElement = target; document.addEventListener( 'mousedown', this.onDocumentMouseDown, false ); document.addEventListener( 'touchstart', this.onDocumentTouchStart, false ); document.addEventListener( 'touchmove', this.onDocumentTouchMove, false ); }, onDocumentMouseDown: function( event ) { document.addEventListener( 'mousemove', this.onDocumentMouseMove, false ); document.addEventListener( 'mouseup', this.onDocumentMouseUp, false ); document.addEventListener( 'mouseout', this.onDocumentMouseOut, false ); mouseXOnMouseDown = event.clientX - windowHalfX; targetRotationOnMouseDown = targetRotation; }, onDocumentMouseMove: function( event ) { mouseX = event.clientX - windowHalfX; targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02; }, onDocumentMouseUp: function( event ) { document.removeEventListener( 'mousemove', this.onDocumentMouseMove, false ); document.removeEventListener( 'mouseup', this.onDocumentMouseUp, false ); document.removeEventListener( 'mouseout', this.onDocumentMouseOut, false ); }, onDocumentMouseOut:function( event ) { document.removeEventListener( 'mousemove', this.onDocumentMouseMove, false ); document.removeEventListener( 'mouseup', this.onDocumentMouseUp, false ); document.removeEventListener( 'mouseout', this.onDocumentMouseOut, false ); }, onDocumentTouchStart: function( event ) { if ( event.touches.length == 1 ) { event.preventDefault(); mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX; targetRotationOnMouseDown = targetRotation; } }, onDocumentTouchMove: function( event ) { if ( event.touches.length == 1 ) { event.preventDefault(); mouseX = event.touches[ 0 ].pageX - windowHalfX; targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05; } }, updateOrbit: function() { orbitElement.rotation.y += ( targetRotation - orbitElement.rotation.y ) * 0.04; } } module.exports = Controls; 对象本身吗? 绑定可能真的令人费解

WatcherTable

我已经尝试过这样做了:

WatcherTable.prototype.setRowData= function(rowData) {
  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(function () {
    this.table.api.sizeColumnsToFit();
  }, 100);
};

但它显然不起作用(我认为这段代码没有任何意义)。

我该如何正确地做到这一点?

谢谢

2 个答案:

答案 0 :(得分:1)

内部setTimeout(function(){...}) this不再链接到WatcherTable个实例。 Here您可以阅读有关this行为的信息。

您可以预先将其保存在prototype.setRowData()这样的

WatcherTable.prototype.setRowData = function(rowData) {

  var thisObj = this;//saving this

  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(function () {
    thisObj.table.api.sizeColumnsToFit();//using thisObj
  }, 100);

};

或者您可以在setTimeout()中使用 ES6 arrow function

WatcherTable.prototype.setRowData = function(rowData) {

  var mockServer = new MockServer();
  mockServer.init(rowData);

  var viewportDatasource = new ViewportDatasource(mockServer);
  this.table.api.setViewportDatasource(viewportDatasource);

  setTimeout(() => {//arrow functions do not affect on 'this'
    this.table.api.sizeColumnsToFit();
  }, 100);

};

答案 1 :(得分:1)

问题不在setRowData函数,而在于setTimeout函数中的回调。

您至少有3种不同的方法来解决它:

使用.bind()

setTimeout(function() {
  this.something();
}.bind(this), 100);

使用保留当前上下文的ES6箭头函数:

setTimeout(() => {
  this.something();
}, 100);

将当前上下文存储在变量中:

var self = this;
setTimeout(function() {
  self.something();
}, 100);