ES2015课程“不是autobind”吗?

时间:2016-10-29 00:43:06

标签: javascript reactjs ecmascript-6

我一直在使用React一段时间了,我已经习惯了我必须手动将我的组件方法绑定到我的组件实例的概念,因为React决定在不自动绑定时“惯用”:

  

因此我们决定不将这个内置到React的类中   模型。如果是,您仍然可以在构造函数中显式预绑定方法   你想要的。

class Counter extends React.Component {
  constructor() {
    super();
    this.tick = this.tick.bind(this);
  }
  tick() {
    ...
  }
  ...
}
     

- https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

我们可以从这个类似的问题http://jsbin.com/citafaradu/2/edit?js,console,output

清楚地看到此示例How to properly bind current object context in ES6 using babelify中的效果

然而,最近有人问我基于原型的课程和新的ES2015课程之间是否有任何区别。直观地说,这个答案应该是一个强调“不!”,因为生成的实例对象自然会有正常的原型并且行为......好吧,就像JS对象一样!而且,未绑定到实例的实例方法的用途是什么?

我试图搜索任何迹象表明这对es6类来说是“idomatically”的,但我发现的只是来自React开发者的其他问题,答案如下:

  

React的ES6类没有自动绑定。这在此处记录:   https://facebook.github.io/react/docs/reusable-components.html#no-autobinding

     

原因是javascript的ES6类没有自动绑定   既不[原文如此]。 React试图不重新发明已经存在的东西   JavaScript的。 ES5没有很好的语法,所以React必须发明   这是自己的课程。但是现在有了ES6课程,我们可以使用标准课程   JavaScript的。
   - “cody”,https://github.com/facebook/react/issues/4065

现在我真的很困惑。这可能是JSX翻译的一招吗?看一下前一个例子的render方法的输出:

{
    key: "render",
    value: function render() {
      return React.createElement("div",null,
        React.createElement("input", { 
          type: "text", onChange: this.handleBindedChange 
        }),
        React.createElement("br", null),
        React.createElement("input", { 
          type: "text", onChange: this.handleUnbindedChange 
        }),
        React.createElement("br", null),
        React.createElement("p",null,"Result: ",this.state.demo)
     );
    }
 }

这里没有骰子 - babel输出使用Object.defineProperty,它会将添加的函数绝对绑定到它们所附加的对象。

所以,我不知所措。我发现的大多数响应都比最终的es2015规范更早 - 因为我在规范本身中找不到任何关于它的内容,是否有一个改变会使React团队的方法无效?这是一个奇怪的翻译工具,我有点误解了吗?反应在幕后做些古怪的事情导致这种情况吗?如果是这样,为什么他们会一再声称这是为了符合ES2015标准呢?如果不是,导致第一个例子中出现的行为的原因是什么?

5 个答案:

答案 0 :(得分:5)

React之所以提到自动绑定,是因为React.createClass自动绑定了所有方法。而这种方法是创建组件的唯一方法。

人们,特别是那些不熟悉JavaScript的人,习惯于将方法传递给其他组件,而this会“神奇地”工作。使用本机ES6类时,此功能消失了,所以他们需要强调差异。

但是,是的,ES6类基本上只是构造函数+原型的语法糖。方法不绑定到对象:

class Foo {
  bar() {}
}

const foo = new Foo();

console.log(foo.hasOwnProperty('bar')); // false
console.log(typeof Foo === 'function'); // true
console.log(Foo.prototype.hasOwnProperty('bar')); // true

答案 1 :(得分:4)

我有类似的问题。类中的方法将能够引用同一个类中的其他方法,因为它们是同一个上下文(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)的一部分。

此示例显示类中的方法可以访问this上的属性,而不受构造函数中的约束:http://jsbin.com/tapokotahi/1/edit?js,console,outputrenderElements方法未绑定,但正在访问this.state

当将类方法传递给事件处理程序时,需要将它们绑定(或定义为箭头函数),因为执行上下文从类的方法更改为事件处理程序的方法。

我同意在阅读React文档时它们似乎令人困惑,它们告诉我们需要在构造函数中绑定方法,但这只有在将方法传递给React的事件处理程序(如{{1 }}

答案 2 :(得分:3)

你可以让ES6类方法在构造函数中用一个小样板自动绑定:



function autobind() {
  for (let prop of Object.getOwnPropertyNames(Object.getPrototypeOf(this))) {
    if (prop === 'constructor' || typeof this[prop] !== 'function') continue;
    this[prop] = this[prop].bind(this);
  }
}

class Test {
  constructor() {
    autobind.call(this);
    this.message = 'hello all!';
  }
  method1(){ return this.method2(); }
  method2(){ console.log(this.message);}
}
let test = new Test();
let b = test.method1;
b();




更新:

此后我发现了一个Babel Plugin来翻译上升的ES类字段&静态属性,可用于需要绑定到this

的函数



class Bork {
    //Property initializer syntax
    instanceProperty = "bork";
    boundFunction = () => {
      return this.instanceProperty;
    }

    //Static class properties
    static staticProperty = "babelIsCool";
    static staticFunction = function() {
      return Bork.staticProperty;
    }
}

let myBork = new Bork;

//Property initializers are not on the prototype.
console.log(myBork.__proto__.boundFunction); // > undefined

//Bound functions are bound to the class instance.
console.log(myBork.boundFunction.call(undefined)); // > "bork"

//Static function exists on the class.
console.log(Bork.staticFunction()); // > "babelIsCool"




答案 3 :(得分:0)

Auto Binding

该库在Node.js中对我来说运行良好。但是我不确定这对React.js是否也适用。

const AUTO_BIND = require("auto-bind");

class Programmer {

  constructor(name, age) {
    this.Name = name;
    this.Age = age;
    AUTO_BIND(this);
    //* For React component
    //* AUTO_BIND.react(this);
  }

  ShowName() {
    console.log(`My name is ${this.Name}`);
  }

  ShowAge() {
    console.log(`My age is ${this.Age}`);
  }

  ShowDetail() {
    this.ShowName();
    this.ShowAge();
  }
}
const programmer = new Programmer("M. Hamza Rajput", 25);

const { ShowDetail } = programmer;

ShowDetail();

console.log(programmer.hasOwnProperty('ShowDetail')); // true
console.log(typeof programmer === 'object'); // true
console.log(Programmer.prototype.hasOwnProperty('ShowDetail')); // true

答案 4 :(得分:-1)

我遇到了没有自动绑定到类的方法的问题。我建立了一个图书馆帮忙:https://www.npmjs.com/package/auto-bind-inheritance

我使用它并感谢任何反馈来改进它。它基于其他几个npm包,我相信我已经改进了。