使用ES2015类而不是autobind
Do ES2015 Classes "not autobind"?
我已经使用React有一段时间了,我已经习惯了必须手动将我的组件方法绑定到我的组件实例的概念,因为React决定不自动绑定:
因此我们决定不把它内建到React的类中模型。您仍然可以显式地在构造函数if中预绑定方法你想要的。
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 -β- 1. - html
我们可以清楚地看到它的效果,在这个例子http://jsbin.com/citafaradu/2/edit?js,console,output中,从这个类似的问题:如何在ES6中使用babelify
正确绑定当前对象上下文然而,最近有人问我基于原型的类和新的ES2015类之间是否有什么区别。直觉上,这个答案应该是一个断然的"不!",作为结果的实例对象将自然地具有正常的原型和行为…就像JS对象一样!而且,没有绑定到实例的实例方法有什么用呢?
我试图寻找任何迹象表明这将是"典型的"es6类的真实,但我所有的结果都是来自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编译的一个技巧吗?看一下前面示例的呈现方法的输出:
{
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团队的方法无效?这是我误解了的一个奇怪的翻译器物吗?是react在幕后做了什么古怪的事情导致了这一切吗?如果是这样,为什么他们反复声称这样做是为了符合ES2015标准?如果不是,是什么导致了第一个例子中的行为?
我也有类似的问题。类中的方法将能够引用同一类中的其他方法,因为它们是同一上下文的一部分(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)。
这个例子展示了类中的方法可以访问this
上的属性,而不需要绑定到构造函数:http://jsbin.com/tapokotahi/1/edit?js,console,output中。renderElements
方法未被绑定,但正在访问this.state
。
类方法在传递给事件处理程序时需要绑定(或定义为箭头函数),因为执行上下文从类的上下文更改为事件处理程序的上下文。
我同意当我们阅读React文档时,它似乎令人困惑,它们告诉我们需要在构造函数中绑定方法,但这只有在将方法传递给React的事件处理程序(如onClick
)时才有必要。
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
你可以让你的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"
我遇到了方法不自动绑定到类的问题。我做了一个库来帮助:https://www.npmjs.com/package/auto-bind-inheritance
我使用它,并感谢任何反馈,以改进它。它基于其他几个npm包,我相信我改进了它们。
自动绑定。
这个库在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
- 为什么我们在ES2015中需要一个新的for循环结构,而我们已经有了for、forEach
- 为什么递归生成器函数没有't在ES2015工作
- 将ECMAScript 6析构函数赋值(ES2015)重构为旧版本的javascript
- ES2015 Promise链-为什么promiseized函数会立即运行
- 缩短ES2015导入路径
- 为什么字符串在 ES2015 中是可迭代对象
- ES2015“导入”在带有--harmony_modules选项的节点v6.0.0中不起作用
- 使用 foreach js es2015 进行动态导入
- ES2015:从覆盖的类调用内部方法
- importing TypeScript vs ES2015
- 如何在ES2015中将模块中的选定函数作为对象导入
- 如何使用ESLint 2禁用某些ES2015功能
- 在ES2015中导入主干模板文本
- 在ES2015中,如何确保所有方法都等待对象初始化?使用ES7装饰器
- ES2015中从函数到类的重构
- ES2015 `import` alternative for `require()()`?
- 调整 ES2015 地图以支持所需的行为
- es2015 中的多行分配
- ES6 ES2015 (Babel) 格式 / 美化 for Sublime for .jsx .js.
- 使用ES2015类而不是autobind