cosyer's Blog

Blog


  • 首页

  • 友链

  • 留言板

  • 归档

  • 关于

  • 搜索

整理 标签

6月
12
更新于
6月12
2019
知识

chrome插件扩展程序开发指南

发表于 2018-11-26 | 热度 ℃
| 字数统计: 1,401 (字) | 阅读时长: 6 (分钟)

什么是chrome extensions

Chrome Extensions,中文名叫 “Chrome浏览器扩展程序”。引用官方文档的描述,翻译一下就是 “可以修改和增强浏览器功能的 H5 小程序”。 它的入口在浏览器窗口的右上角,地址栏的最右边


阅读全文 »
7月
18
更新于
7月18
2020
知识

webapck4零配置了解一下

发表于 2018-11-26 | 热度 ℃
| 字数统计: 658 (字) | 阅读时长: 3 (分钟)

webpack4 最主要的卖点便是零配置,要想成为一位webpack配置工程师怎么能不开始了解呢?话不多说,让我们开始体验 webpack 4 的一些特性。

entry 和 output

  1. 创建空目录,初始化配置

    1
    2
    3
    mkdir webpack4-quickstart
    cd webpack4-quickstart
    npm init -xyz
  2. 安装相关依赖

    1
    2
    npm i webpack --save-dev
    npm i webpack-cli --save-dev
  • webpack: 即 webpack 核心库。它提供了很多 API, 通过 Node.js 脚本中 require(‘webpack’) 的方式来使用 webpack。
  • webpack-cli:是 webpack 的命令行工具。webpack 4 之前命令行工具是集成在 webpack 包中的,4.0 开始 webpack 包本身不再集成 cli。
  1. package.json添加构建命令
    1
    2
    3
    "scripts":{
    "build":"webpack"
    }

阅读全文 »
8月
31
更新于
8月31
2020
知识

实现前端路由

发表于 2018-11-24 | 热度 ℃
| 字数统计: 1,788 (字) | 阅读时长: 8 (分钟)

现代的前端框架react/vue/angular都有路由router的概念,通过手写实现可以帮助我们更好地了解它的工作原理。它们都推荐单页面应用 SPA 开发模式,在路由切换时替换 DOM Tree 中最小修改的部分 DOM,来减少原先因为多页应用的页面跳转带来的巨量性能损耗。它们都有自己的典型路由解决方案,@angular/router、react-router、vue-router等。

一般来说,这些路由插件总是提供两种不同方式的路由方式: Hash 和 History,有时也会提供非浏览器环境下的路由方式 Abstract(支持所有 JavaScript 运行 环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式)。

实现路由的2种方式

  1. hash模式 状态保存需要另行传递
  2. history模式 原生提供了自定义状态传递的能力

缺点

hash: 地址栏会多出一个#号,对url造成影响,在某些场景下如微信支付有坑。 history: 兼容性差,直接访问报404,需要服务器做处理。

基本原理

  • hash 主要原理是通过监听 # 后的 URL 路径标识符的更改而触发的浏览器 hashchange 事件(当 location.hash 发生改变时,将触发这个事件)

注意: Hash 方法是利用了相当于页面锚点的功能,所以与原来的通过锚点定位来进行页面滚动定位的方式冲突,导致定位到错误的路由路径,因此需要采用别的办法。

  • history 则基于 pushState 和 popState replaceState

Hash 模式是使用 URL 的 Hash 来模拟一个完整的 URL,因此当 URL 改变的时候页面并不会重载。History 模式则会直接改变 URL,所以在路由跳转的时候会丢失一些地址信息(只是动态的通过js操作window.history来改变浏览器地址栏里的路径,并没有发起http请求),在刷新或直接访问路由地址的时候会匹配不到静态资源。因此需要在服务器上配置一些信息,让服务器增加一个覆盖所有情况的候选资源。

history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。


阅读全文 »
7月
05
更新于
7月05
2020
知识

js函数柯里化

发表于 2018-11-22 | 热度 ℃
| 字数统计: 1,088 (字) | 阅读时长: 5 (分钟)

函数柯里化定义

函数柯里化(function currying)又称部分求值。一个currying的函数首先会接受一些参数,接受了这些参数后,

该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包里被保存起来。待到函数真正需要求值的时候,之前传入的参数都会被一次性用于求值。

把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数。

顾名思义,柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理批特定的需求。这增加了函数的适用性,但同时也降低了函数的适用范围。

1
2
3
4
5
6
7
8
9
10
11
function add(x,y){
return x + y;
}
// 函数只传入一个参数的时候实现加法
function curry(x){
return function(y){
return x + y;
}
}
var add2 = curry(1);
add2(1) // 2 即curry(1)(1)

阅读全文 »
7月
11
更新于
7月11
2020
JS

实现双向绑定

发表于 2018-11-07 | 热度 ℃
| 字数统计: 3,272 (字) | 阅读时长: 15 (分钟)

主流的双向绑定方法 1.发布-订阅模式 通过使用 get 和 set 的方式获取数据然后更新数据,其原理就是监听页面中某个具体元素的事件,然后将其最新的值手动 set 到 数据中,同时订阅 model 层的改变,然后触发页面的渲染更新

2.脏检测 通过对比数据是否有变更,来决定是否更新视图。最简单的可以通过定时轮询去检测数据的变动。Angular 只有在指定事件触发时进入脏检测:

  • DOM事件,比如用户输入文本点击按钮等(ng-click)
  • XHR响应事件 浏览器 Location 变更
  • Timer事件
  • 执行 $digest() 或 $apply();

脏检查的主要原理是在将数据绑定到 View 的时候,就在监听器列表(scope 作用域中的监听队列 watchList)中插入一条监听器,当触发 UI 事件或者 Ajax 请求时,就会触发脏检查($digest cycle), 在 $digest 流程中,将遍历每个数据变量的 watcher,比较它的新旧值。当新旧值不同时,触发 listener 函数,执行相关的更新逻辑。这个过程将会一直重复,直到所有数据指令的新旧值都相同为止。

脏检查虽然可以达到实现双向绑定,但是当页面中绑定的 watcher 过多时,就会引发性能问题。所以 angular 在进行 $digest 检测时,会限制循环检查的次数最少2次,最多10次,防止无效的检查。

3.数据劫持 通过 ES5 的 Object.defineProperty() 来劫持数据属性的 getter 和 setter, 在数据变动时触发订阅者(watcher),从而触发相应的监听回调更新视图。

  • Observer 对数据的所有属性进行监听其 getter 和 setter
  • Compile 是一个指令解析器,对 MVVM 实例的所有元素指令进行解析,并渲染成 model 中的绑定数据,当数据进行更新时,也能替换为更新后的值。
  • Watcher 作为 Compile 和 Observer 的桥梁,能够订阅数据属性的更新,然后执行相应的监听回调
  • Deps 用于存放监听器数组,主要用来保存 Watcher
  • Updater 执行更新操作,针对不同的指令进行不同的更新操作,如 v-model, v-class, v-html 等类型的指令。
  • MVVM 作为入口函数,整合以上所有的功能。

vue-mvvm

Observer 劫持了所有数据属性的 getter 和 setter,当数据发生改变时,就会通知 deps 中所有 watcher 的更新操作,进而触发页面的重新渲染,这是修改 Model 层从而引发 View 层的重新渲染。 在 Compile 中监听可输入元素的事件,然后将新值更新到 model 的数据中,这是修改 View 层触发的 Model 层的修改。

  • 用户名或者邮箱跟github没有关联上, github认为不是你提交的, 不统计。
  • fork 的项目, 不统计
  • 没有在版本库的master【默认分支】上提交

解读


阅读全文 »
7月
28
更新于
7月28
2020
知识

深浅拷贝

发表于 2018-10-31 | 热度 ℃
| 字数统计: 1,345 (字) | 阅读时长: 7 (分钟)

深浅拷贝概念

深拷贝和浅拷贝只针对象 Object, Array 这样的复杂对象(引用类型)的。

复制引用(引用类型)的拷贝方法称之为浅拷贝,创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果

属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

深拷贝就是指完全的拷贝一个对象,将原对象的各个属性递归复制下来。这样即使嵌套了对象,两者也相互分离。

浅拷贝 对基本类型拷贝值,引用类型拷贝引用

Object.assign()

扩展运算符…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var shallowCopy = function(obj) {
if (typeof obj !== 'object') return; // 只拷贝对象
var newObj = obj instanceof Array ? [] : {}; // 根据obj的类型判断是新建一个数组还是对象
for (var key in obj) { // 遍历obj,并且判断是obj的属性才拷贝
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}

function shallowCopy2(source) {
if (source === null || typeof source !== 'object') return source;
const copy = Array.isArray(source) ? [] : {};

Object.keys(source).forEach(key => {
copy[key] = source[key];
});
return copy;
}

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
shallowObj.arr[1] = 5;
console.log(obj.arr[1]) // 5 互相影响 指向了同一块内存地址
shallowObj.a = 5;
console.log(obj.a) // 1

深拷贝(将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。)

JSON.parse(JSON.stringify(a)): 性能最快

具有循环引用的对象时,报错 当值为函数、undefined、或symbol时,无法拷贝

递归复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 不考虑循环引用
var deepCopy = function(obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
shallowObj.arr[1] = 5;
console.log(obj.arr[1]) // 3 没有影响 重新拷贝了新数据
shallowObj.a = 5;
console.log(obj.a) // 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 不考虑循环引用
const clone = function(data){
if(typeof data !== 'object'){
return data;
}
let keys = Object.keys(data);
let result = Array.isArray(data) ? [] : {};
keys.forEach(key=>{
if(typeof data[key] === 'object'){
result[key] = clone(data[key]);
}else{
result[key] = data[key];
}
})
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 考虑循环引用 只考虑了普通的 object和 array两种数据类型
const clone = function(data){
let map = new WeakMap(); // 这里用WeakMap弱引用,会自动回收,不需要手动处理置为null
function dp(obj){
if(typeof obj !== 'object'){
return obj;
}
let o = map.get(obj);
if(o){
return o;
}
let result = Array.isArray(obj) ? [] : {};
map.set(obj, result);
let keys = Object.keys(obj);
keys.forEach(key=>{
if(typeof obj[key] === 'object'){
result[key] = dp(obj[key]);
}else{
result[key] = obj[key];
}
})
return result;
}
return dp(data);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// 终极版
const mapTag = '[object Map]';
const setTag = '[object Set]';
const arrayTag = '[object Array]';
const objectTag = '[object Object]';
const argsTag = '[object Arguments]';

const boolTag = '[object Boolean]';
const dateTag = '[object Date]';
const numberTag = '[object Number]';
const stringTag = '[object String]';
const symbolTag = '[object Symbol]';
const errorTag = '[object Error]';
const regexpTag = '[object RegExp]';
const funcTag = '[object Function]';

const deepTag = [mapTag, setTag, arrayTag, objectTag, argsTag];


function forEach(array, iteratee) {
let index = -1;
const length = array.length;
while (++index < length) {
iteratee(array[index], index);
}
return array;
}

function isObject(target) {
const type = typeof target;
return target !== null && (type === 'object' || type === 'function');
}

function getType(target) {
return Object.prototype.toString.call(target);
}

function getInit(target) {
const Ctor = target.constructor;
return new Ctor();
}

function cloneSymbol(targe) {
return Object(Symbol.prototype.valueOf.call(targe));
}

function cloneReg(targe) {
const reFlags = /\w*$/;
const result = new targe.constructor(targe.source, reFlags.exec(targe));
result.lastIndex = targe.lastIndex;
return result;
}

function cloneFunction(func) {
const bodyReg = /(?<={)(.|\n)+(?=})/m;
const paramReg = /(?<=\().+(?=\)\s+{)/;
const funcString = func.toString();
if (func.prototype) {
const param = paramReg.exec(funcString);
const body = bodyReg.exec(funcString);
if (body) {
if (param) {
const paramArr = param[0].split(',');
return new Function(...paramArr, body[0]);
} else {
return new Function(body[0]);
}
} else {
return null;
}
} else {
return eval(funcString);
}
}

function cloneOtherType(targe, type) {
const Ctor = targe.constructor;
switch (type) {
case boolTag:
case numberTag:
case stringTag:
case errorTag:
case dateTag:
return new Ctor(targe);
case regexpTag:
return cloneReg(targe);
case symbolTag:
return cloneSymbol(targe);
case funcTag:
return cloneFunction(targe);
default:
return null;
}
}

function clone(target, map = new WeakMap()) {

// 克隆原始类型
if (!isObject(target)) {
return target;
}

// 初始化
const type = getType(target);
let cloneTarget;
if (deepTag.includes(type)) {
cloneTarget = getInit(target, type);
} else {
return cloneOtherType(target, type);
}

// 防止循环引用
if (map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);

// 克隆set
if (type === setTag) {
target.forEach(value => {
cloneTarget.add(clone(value, map));
});
return cloneTarget;
}

// 克隆map
if (type === mapTag) {
target.forEach((value, key) => {
cloneTarget.set(key, clone(value, map));
});
return cloneTarget;
}

// 克隆对象和数组
const keys = type === arrayTag ? undefined : Object.keys(target);
forEach(keys || target, (value, key) => {
if (keys) {
key = value;
}
cloneTarget[key] = clone(target[key], map);
});

return cloneTarget;
}

module.exports = {
clone
};

尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

9月
07
更新于
9月07
2020
知识

js判断数据类型

发表于 2018-10-31 | 热度 ℃
| 字数统计: 541 (字) | 阅读时长: 3 (分钟)

typeof

typeof一般只能返回如下几个结果:number,boolean,string,function,object,undefined字符串

对于Array,null等特殊对象使用typeof一律返回object,这正是typeof的局限性。

typeof表示是对某个变量类型的检测,基本数据类型除了null都能正常的显示为对应的类型,引用类型除了函数会显示为’function’,其它都显示为object。

1
2
3
var fn = new Function ('a', 'b', 'return a + b')

typeof fn // function

instanceof

instanceof适用于检测对象,它是基于原型链运作的。

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。换种说法就是如果左侧的对象是右侧对象的实例, 则表达式返回true, 否则返回false 。

instanceof对基本数据类型检测不起作用,因为基本数据类型没有原型链。可以准确的判断复杂数据类型。

1
2
3
4
5
6
7
8
9
10
11
[1, 2, 3] instanceof Array // true 
/abc/ instanceof RegExp // true
({}) instanceof Object // true
(function(){}) instanceof Function // true

// 基于constructor
a.constructor === Array;
// 基于Object.prototype.isPrototypeOf
Array.prototype.isPrototypeOf(a);
// 4.基于getPrototypeOf
Object.getPrototypeOf(a) === Array.prototype;

Object.prototype.toString.call

可以检测各种数据类型,推荐使用。

1
2
3
4
5
6
7
8
9
10
Object.prototype.toString.call([]); // => [object Array] 
Object.prototype.toString.call({}); // => [object Object]
Object.prototype.toString.call(''); // => [object String]
Object.prototype.toString.call(new Date()); // => [object Date]
Object.prototype.toString.call(1); // => [object Number]
Object.prototype.toString.call(function () {}); // => [object Function]
Object.prototype.toString.call(/test/i); // => [object RegExp]
Object.prototype.toString.call(true); // => [object Boolean]
Object.prototype.toString.call(null); // => [object Null]
Object.prototype.toString.call(); // => [object Undefined]
1
2
3
4
5
6
7
8
9
let isType = type => obj => {
return Object.prototype.toString.call( obj ) === '[object ' + type + ']';
}

var isString = isType( 'String' );
var isArray = isType( 'Array' );
var isNumber = isType( 'Number' );

console.log( isArray( [ 1, 2, 3 ] ) ); //true

constructor

constructor也不是保险的,因为constructor属性是可以被修改的,会导致检测出的结果不正确。

1
2
3
4
5
6
7
8
9
10
11
12
console.log([].constructor === Array)   // true
function a() {}
console.log(a.constructor === Function) // true
console.log(12.constructor === Number) // true
console.log('22'.constructor === String) // true
console.log([] .constructor === Array) // true
console.log({a: 1}.constructor === Object) // true
console.log(true.constructor === Boolean) // true
console.log(json.constructor === Object) // true
console.log((new Date()).constructor === Date) // true
console.log(reg.constructor === RegExp) //true
console.log(error.constructor === Error) // true
8月
24
更新于
8月24
2020
知识

js创建对象实现继承

发表于 2018-10-31 | 热度 ℃
| 字数统计: 3,327 (字) | 阅读时长: 15 (分钟)

今天10月31日,万圣节前夜。希望ff的病早点好,身体健康。

创建对象(字面量、构造函数、create方法、调用函数返回对象)

1
2
3
4
5
6
7
8
9
var obj = {} // 字面量 
var obj = new Object() // 很少见,性能低 没有形参时可省略()
var obj = Object.create(null) // 以xx为原型创建对象
var obj = Object.assign({}) // 复制到目标对象
// Object.assign()还可以去除多余的参数覆盖
Object.assign({ a: 1, b: 2 }, { b: 3, c: 3 })
const newObj = { ...{ a: 1, b: 2 }, ...{ b: 3, c: 3 } }
// {a: 1, b: 3, c: 3}
// Object() ==> {}

阅读全文 »
12月
02
更新于
12月02
2020
JS

高逼格的JS代码

发表于 2018-10-30 | 热度 ℃
| 字数统计: 1,551 (字) | 阅读时长: 8 (分钟)

黑科技JS代码整理 是不是很void 666

一行代码实现评级

1
"★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);定义一个变量rate是1到5的值

SB、NB、Hello World

1
2
3
4
5
(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]

([][[]]+[])[+!![]]+([]+{})[!+[]+!![]]

([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[+[]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[]))+([]+{})[+!![]]+(!![]+[])[+!![]]+(![]+[])[!+[]+!![]]+([][[]]+[])[!+[]+!![]]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+[])+(+!![]+[]))

错误处理的正确方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
something
} catch (e) {
window.location.href =
"http://stackoverflow.com/search?q=[js]+" +
e.message;
}
// 百度版
try {
something
} catch (e) {
window.location.href =
"https://www.baidu.com/s?wd=" +
e.message;
}

阅读全文 »
7月
22
更新于
7月22
2020
知识

babel的.babelrc配置

发表于 2018-10-29 | 热度 ℃
| 字数统计: 488 (字) | 阅读时长: 2 (分钟)

Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。Babel 内部所使用的语法解析器是 Babylon

一个基本的.babelrc配置:

1
2
3
4
5
6
7
{
"presets": [
"env",
"stage-0"
],
"plugins": ["transform-runtime"]
}

阅读全文 »
12
陈宇(cosyer)

陈宇(cosyer)

不去做的话永远也做不到。

159 日志
10 分类
51 标签
RSS
GitHub Twitter E-Mail FB Page
推荐阅读
  • Callmesoul
  • JsTips
  • Personal Site
  • Resume
© 2021 陈宇(cosyer)
终于等到你(UV):   |   欢迎再来(PV):
Blog总字数: 312.5k字
苏ICP备17005342号-1