本文介绍了 Java 初学者应该知道的一些技巧和陷阱。如果你是老司机,就当做回顾了,哪里有写的不好的地方欢迎指出。
1. 你是否尝试过对一个数字数组进行排序呢?
Java 中的 sort() 默认是按字母排序的。所以比如你这样 [1,2,5,10].sort(),会输出[1,10,2,5]。
正确的排序可以使用 [1,2,5,10].sort((a, b) => a — b)。
是不是很简单,这个知识点是告诉你第一种方式排序是有问题的。
2. new Date() 很好用 举报
new Date() 可以接收:无参数:返回当前时间;1 个参数 x:返回 1970 年 1 月 1 日 + x 毫秒时间。Unix 的小伙伴知道为什么是这样;new Date(1,1,1) 返回 1901 年 2 月 1 日:第一个 “1” 代表 1900 年以后的第 1 年;第二个 “1” 代表这一年的第 2 个月(并不是像你想象的那样从 1 月开始);第三个 “1” 代表这个月的第 1 天(这个确实是如你想象的那样从 1 开始)。new Date(2017,1,1) :这并不是表示 1900 + 2017了,它就是表示 2017 年 1 月 1 日。3. 替换,实际上并没有替换
对于原始串不被替换掉,我是双手赞同的,我不喜欢一个函数的输入总是在变化。另外你应该知道replace 只会替换第一个匹配上的字符。
lets = "bob"constreplaced = s.replace( 'b', 'l') replaced === "lob"// 只替换第一个匹配上的s === "bob"// 原始串始终没变
如果你想替换所有的,那就是用正则符 /g:
"bob".replace( /b/g, 'l') === 'lol'//替换所有串 4. 小心使用比较 // These are ok'abc'=== 'abc'// true1=== 1// true// These are not[ 1, 2, 3] === [ 1, 2, 3] // false{a: 1}=== {a: 1}// false{}=== {}// false
原因:[1,2,3] 和 [1,2,3] 是两个数组,它们只是恰巧值相等罢了,他们的引用是不同的,所以不能用简单的 === 来比较。
5. 数组不是原始类型 typeof{} === 'object'// truetypeof'a'=== 'string'// truetypeof1=== number// true// But....typeof[] === 'object'// true
想知道你的变量是不是数组,仍然可以使用 Array.isArray(myVar)。
6. 闭包
这是很出名的一道 Java 面试题:
constGreeters = [] for( vari = 0; i < 10; i++) { Greeters.push( function() { returnconsole.log(i) }) } Greeters[ 0]() // 10Greeters[ 1]() // 10Greeters[ 2]() // 10
你预期的是输出:0,1,2...吗?你知道这是为什么吗?你知道怎么 fix 吗?
我来提两种可能的解决方案来解决这个问题:第一种:使用 let,不用 var。Duang!解决了~
let 和 var 的区别是作用域。var 的作用域是最近的函数块。而 let 的作用域是最近的封闭块。如果两个都是在块外的,那两个都是全局的。最近的封闭块,要比最近的函数块范围小。这里是源码。第二种:使用 bind。Greeters.push( console.log.bind( null, i))
还有很多方法可以解决这一问题,这里列出了我个人的两种最优选择。
7. 聊一聊 bind
你觉得下面的代码会输出什么?
classFoo{ constructor(name) { this.name = name } greet () { console.log( 'hello, this is ', this.name) } someThingAsync () { returnPromise.resolve() } asyncGreet () { this.someThingAsync() .then( this.greet) } } new Foo( 'dog').asyncGreet()
给你点提示,你认为是否会抛出异常呢?Cannot read property 'name' of undefined。
原因:greet 没有在恰当的上下文中执行。依旧,有很多种方法解决这个问题。第一种:我个人比较喜欢如下解决方法。asyncGreet () { this.someThingAsync() .then( this.greet.bind( this)) }
这种方式可以保证 greet 是在类已经实例化以后被调用。第二种:如果你想确保 greet 始终可以正确调用,可以绑定到构造函数中。classFoo{ constructor(name) { this.name = name this.greet = this.greet.bind( this) } } 第三种:你还应该知道箭头函数(=>)可以保护上下文,也可以解决这个问题。asyncGreet () { this.someThingAsync() . then( ()=>{ this.greet() }) }
虽然我觉得最后一种解决方案这个例子中很不优雅……
结束语
恭喜!到现在你知道了 Java 中的一些坑,和一点技巧。Java 中还有很多知识等待着你去学习,不过起码在这几个问题上,你不会再犯错误了。Cheers! o/
本文作者:Aurélien Hervé
编译:胡子大哈
翻译原文:http://huziketang.com/blog/posts/detail?postId=58e06b98a58c240ae35bb8dd
英文连接:Who said java was easy ?
-END-
留言与评论(共有 0 条评论) |