String.prototype.someFunction = function () { //some code }
(您可能需要查看this question以了解有关扩展对象原型的更多信息.)
是的我可以在组件旁边定义它并在其中使用它.但最好和最干净的方法是什么?
我应该将其作为类方法还是在componentDidMount或其他内容中编写?
编辑:
在React(或JavaScript)中扩展对象原型甚至是“OK”吗?
解决方法
– 细致的答案 –
What I’m trying to do is extend pure JavaScript classes,like String class,which is a very common task in javascript
Is it even “OK” to extend object prototype in React (or in JavaScript) at all?
在JavaScript中扩展/修改原生原型是一个controversial topic,与你所说的相反,并不是大多数专业开发人员经常做的事情. general consensus是@L_404_4@,因为它打破了封装原则并修改了全局状态.但是,与许多规则一样,可能会有罕见的例外情况.例如:你正在开发一个不需要生产质量的玩具项目,你是唯一一个会接触该代码库的开发者,或者你的代码永远不会成为其他任何人的依赖.
如果你有充分的理由并且真正了解自己正在做什么,并且完全了解修改运行时环境和依赖项的本机数据类型/行为的潜在后果,那么您可能会发现一些有效的用途这种做法的情况.但很可能不是,或者至少不是经常.几乎没有.
如果你只是在方便/语法糖之后,你最好不要使用实用功能(来自lodash,下划线或ramda等)并学习练习功能组合.但是,如果您真的致力于面向对象的范例及其所有状态和隐式参数(iexdoIt()接收此(x)及其所有成员作为隐式参数),那么您应该只是“子类化”本机数据类型而不是修改它们.
所以不要像这样改变一个类的原型:
String.prototype.somethingStupid = function () { return [].map.call(this,function(letter) { if ((Math.random() * 1) > .5) return letter.toUpperCase() else return letter.toLowerCase() }).join('') } console.log('This is a silly string'.somethingStupid())
您将创建一个子类(仅适用于ES6类语法),如下所示:
class MyString extends String { constructor(x = '') { super(x) this.otherInstanceProp = ':)' } somethingStupid() { return [].map.call(this,function(letter) { if ((Math.random() * 1) > .5) return letter.toUpperCase() else return letter.toLowerCase() }).join('') } } const myStr = new MyString('This is a silly string') console.log(myStr) console.log(myStr.valueOf()) console.log(myStr.somethingStupid() + ',don\'t you think?')
这个子类在各方面都像内置String一样工作,当然除了你不能写像字符串文字这样的MyString文字.
I created a pure React application using create-react-app. I would like to extend the String class and use it in one or more components … Yes I can define it beside a component and use it within. But what is the best and cleanest way? … Should I write it as a class method or inside componentDidMount or something else?
因为修改内置原型(通过改变String.prototype之类的东西)会改变应用程序的全局状态,所以你只需执行一次,几乎可以肯定在执行任何其他代码之前(因为你正在设置全局)字符串表示所有代码执行后的状态.因此,在React组件实例方法中更改内置原型并没有多大意义.
如果您要做脏事,我建议为您要修改的每个本机类型创建一个单独的模块,并将这些模块保存在src / lib / extend-built-ins /之类的某个位置,然后导入它们是src / index.js中的第一件事.你不需要出口任何东西.执行import src / lib / extend-built-ins / String.js将执行代码,这将改变您的全局状态.这将提供至少合适的组织,并确保在应用程序的其余代码运行之前完全修改您的应用程序环境.这样,您可以在整个应用程序中使用扩展类型,而无需考虑从某处导入它们.
如果你要去子类化路由(类MyThing扩展NativeThing),那么我建议你在src / lib / native-subclasses /之类的单独模块中类似地定义自定义类.但在这种情况下,您必须将类构造函数导入到要使用它们的任何/每个模块中.
但是,如果您想开发干净,可测试,可重构的代码,这些代码对其他人和您未来的自己都很容易理解,那么您不应该这样做.相反,考虑采用React及其生态系统的函数式编程原理.任何人都可以快速阅读和理解纯函数,因此使用它们来完成数据和状态转换,而不是依赖于修改全局对象等难以跟踪的黑客攻击.理解这个小小的黑客可能是可爱而微不足道的,但在项目中甚至一次这样做可以促进和鼓励自己和他人使用额外的快捷方式和反模式.