分类 前端技巧 下的文章

趣味js-只用1和特殊字符生成字符串


180306更新:发现有个http://www.jsfuck.com/ ,上面就做了我想做的东西。也找到了C的生成方法

同时,由于+[]=0,+!+[]=1。我们可以把1也给省略


前言

今天逛justjavac 老哥的博客看到了类似下面的代码

(+([]+(11^(1<<1))+((1+1)<<(1+1))+(11>>>1)+(1^1)+((11>>1)+(1<<1))+(-~1)+(-~1+1)+(1^1)+(1^1)))[(!!1+[])[1^1]+([]+{}+[])[1]+(([]+{})[([]+{})[11-1>>1]+[[],[]+{}+[]][[]+1][1]+(/^/[1]+[])[1|1>>1|1]+[{},11^1,!{}+[]][1+1][1<<1^1]+(11/!{}+{})[~1+(11^1)+~1]+[!!{}+{}][[]&111][1&1]+(/^/[111]+[])[11^11]+[{},[{}]+{},1][1+[]][11-~1+11>>1]+(!!1+{})[1&1>>1]+([]+{1:1}+[])[1|1]+[[]+!!1][111>>>111][1<<1>>1]]+[])[([]+![111])[1|1<<1|1]+[/=/,[]+[][11]][1|[]][1>>1]+([{}]+{})[1+!![1]]+[1,!1+/~/][1%11][1^1<<1]+(!!1+[])[1^1]+[!!/-/+/-/][11%11][+!!1]](11^1<<1,-~11>>1)](~1-~(11^1)<<1<<1)

输出:gahing

实现的原理是什么?

原理

了解 js 隐式类型转换(不懂可以参考这里)的都知道

我们可以通过执行!1+[]得到"false"

具体原理是 false+object 操作会先去调用object的valueOf()方法 发现其值=this

继续调用toString()方法得到"", 结果即false+"" = "false"(又去做了隐式转换)

故我们通过数组下标就可以拿到想要的字符f,a,l,s,e

类似的方法我们还能够拿到

!1+[] = "false"
!!1+[] = "true"
1/[]+[] = "Infinity"
[]/[]+[] = "NaN"
[]+{} = "[object Object]"
[]+/^/[1] = "undefined" /* /^/是正则 */
[]+/\:@$/ = "/\:@$/" /*键盘可见特殊字符放/\ /其中(\用于转义)获取比如拿:就是[1]*/

//可拿到的小写字母有=abcdef ijln orst uy

然后你会发现,26个字母还是有好多不在上面的,并不能通过每次去上面拿字符然后再做拼接


Vue 第一个组件,浏览器后退无法触发beforeRouteLeave的问题与解决


已提issue: https://github.com/vuejs/vue-router/issues/1951

现象

加载第一个组件(这里的第一个意思是浏览器历史记录的第一个,后文称为待监听组件)时,正常跳转其他页面可以触发beforeRouteLeave。 但是按浏览器的后退按钮监听不到该事件。

解决方案

目前采用比较土且不实用的解决方案。加一层组件,再router.push到待监听组件,使得待监听组件非第一个组件,可以正常监听beforeRouteLeave事件。

注意点:

由于打乱了原来的路由。需要在main.js中添加全局的路由监听

router.beforeEach((to, from, next) => {
  if (to is '用于跳转的组件' && from is '待监听组件') {
    router.go(-1) 
    next(false)
  } else {
    next()
  }
  // 这样当从一个普通页面A进入待监听组件时,在待监听组件中按返回键时能正常进入A
})

存在的问题:

  1. 若访问不是访问中转组件而是直接访问待监听组件,则没有效果
  2. 增加路由后,多了白屏时间。

可能官方有什么解决方案,或者我用错了。欢迎评论

后记:

VUE路由控制是基于h5的history API实现

beforeRouteLeave又是基于window.onpopstate

该事件的官方描述:

Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event is only triggered by doing a browser action such as clicking on the back button (or calling history.back() in JavaScript). And the event is only triggered when the user navigates between two history entries for the same document.

简而言之:该事件仅在按了浏览器按钮或者调用history.back()方法时生效,且在同一document的两条历史记录条目间的导航才会生效,而上文出现的原因正是不属于同一document