在archlinux下,所有的程序安装都会生成一个像windows快捷方式的文件,这个目录在我的archlinux下
/usr/share/applications目录下,可以看到很多以扩展名为desktop的文件。而文件的默认打开程序就是关联在这些程序图标下。

当前每个文件格式默认关联的程序内容是放在:~/.local/share/applications/defaults.list。

linux下可以使用xdg-open file的方式来打开文件,不使用任何DE(desktop enviorment),比如gnome、kde,xfce4等。使用下面的命令查询并修改一个文件的默认打开程序:

# 查询文件类型
$ xdg-mime query filetype some.xls
application/msword; charset=binary
# 查询该文件类型的默认打开方式
$ xdg-mime query default application/msword
# 修改文件的默认打开方式
$ xdg-mime default libreoffice-writer.desktop application/msword

设置文件夹的默认打开程序也可以用这种方法:

$xdg-mime query filetype /home/
inode/directory
$xdg-mime query default inode/directory
$xdg-mime default Thunar-folder-handler.desktop inode/directory

原文链接:http://willam2004.iteye.com/blog/1299151

神秘博士Doctor Who S09 E05: the Doctor’s face

  • I’m so sick of losing.

  • You didn’t lose.You saved the town.

  • I don’t mean the war. I’ll lose any war you like. I’m sick of losing people.

  • My face.

  • Who frowned me this face?

  • Why this one?

  • Why did I choose this face?

  • Doctor, what’s wrong with your face?

  • I think I know why I chose it.

  • It’s like I’m trying to tell myself something.

  • I think I know what I’m trying to say.

  • Just someone.

  • Not the whole town.

  • Just save someone.

  • Come with me.

  • I know where I got this face,

  • and I know what it’s for.

  • OK, what’s it for?

  • To remind me.

  • To hold me to the mark.

火线The Wire: Old Cases S01 E04

Det. James ‘Jimmy’ McNulty: How long you been in the pawn shop unit?

Det. Lester Freamon: Thirteen years and four months.

Det. James ‘Jimmy’ McNulty: Thirteen years?

Det. Lester Freamon: And four months.

Det. James ‘Jimmy’ McNulty: I gotta ask you, what exactly does a police officer assigned to the pawn shop unit do?

Det. Lester Freamon: You intake reports from registered pawn shops on all items valued over $50. Then you make an index card for that item. Then you file that index card. If someone wants to find out if something stolen has been pawned, we look to see if we have an index card. If we do, we do. If we don’t, we don’t.

Det. James ‘Jimmy’ McNulty: You did that for thirteen years?

Det. Lester Freamon: And four months.

Det. James ‘Jimmy’ McNulty: Why’d you ask out of homicide?

Det. Lester Freamon: Wasn’t no “ask” about it.

Det. James ‘Jimmy’ McNulty: You got the boot?

Det. Lester Freamon: Uh-huh.

Det. James ‘Jimmy’ McNulty: What’d you do to piss ‘em off?

Det. Lester Freamon: Police work.

Det. James ‘Jimmy’ McNulty: I think I need to buy you a drink.

Det. Lester Freamon: Just one?

JavaScript的对象复制存在一些容易犯错的位置,从下面代码可以看出来:
直接赋值:

1
2
3
4
5
6
7
let obj = {
cat: 1,
a: { b: {c: 1} }
}
const sameObj = obj;
obj.a.b.c =2;
console.log(obj === sameObj); // ture

明明更改了初始的对象obj,但是这两个对象还是完全相等。所以这赋值操作与一般的变量赋值是有区别的。js中这种直接赋值来复制对象是将原对象在内存中的引用(c语言中的指针)复制了过去,并没有给新的对象加入新的内存空间。当这两个对象中的一个对象改变时,于是这块内存也改变了,但是这两个对象都是指向这块内存空间,于是就发生了这种情况:当一个对象改变时,这两个对象都会改变。

浅拷贝:所以要使用新的方法来复制对象:例如 Object.keys(),Object.assign(),for(let … in Obj)等方法来复制对象const a = {};``a = { ...ArrObj }Object.assign({}, Obj)

1
2
3
4
5
const obj2 = Object.assign({}, obj);    
obj.cat = 2;
obj.a.b.c =2;
console.log(obj2.cat, obj.cat === obj2.cat); // 1, false
console.log(obj2.a.b.c, obj2.a.b.c === obj.a.b.c) // 2, true

第一条打印的结果是我们想要的,新对象与原始对象不再有联系。但是第二条打印结果却又出现来跟直接赋值来复制对象相识的情况:改变一个对象的属性值,另一个对象也相应的改变了。这是因为上述的复制方法也都是只把第一层属性值重新用赋值的方式复制了一下,如果第一层的属性值仍然是指向对象的引用,这些方法复制的依然是指针,所以改变其中一个对象第二层以上的属性值,还是会导致两个对象同时改变。

理解之后可以思考一下下面的打印结果

1
2
obj.a = 1;
console.log(obj2.a.b.c); // 2

深拷贝:使用const newObj = JSON.parse(JSON.stringify(obj))可以实现复制对象是不再复制指针,进而两个对象不再有关联。可以这样理解:对象先转换成字符串,对象的指针信息自然就不再保存下来了,从这个字符串生成的对象也就没有了指针的关联,两个对象不再有任何关联。这种方法只有在原对象是json格式时有效,因为这种复制方法也会将原对象的方法(属性为函数)丢失。

ps:这样设计的目的是为了节省内存,所以为了这几kb的内存我就还是忍了吧!

递归函数深层复制

React组件更新的四个途径

  1. 首次渲染Initial Render
  2. 调用this.setState (并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
  3. 父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
  4. 调用this.forceUpdate
    如图所示
    React

原作者:linjinhe

链接:http://www.jianshu.com/p/4784216b8194

  • 图片按钮<input name="submit" type="image" value="ee" src="12.jpg" />
  • img下面有4px留白
  • 使用title属性显示提示信息
  • 空格:&nbsp;
  • <hr />color属性设置颜色
  • ie兼容性<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  • 只要是有src或href的HTML标签都有跨域的能力。
  • 网页中的空格转义字符&nbsp;在命令行中不能识别为正常的空格,会导致命令执行出错
  • 将dom元素关联自定义变量:加入属性data-*
1
2
3
4
5
6
<img
data-value="31940"
onclick={(e) => {
console.log(e.target.dataset.value);
}}
/>
  • dom元素绑定事件,传入当前元素
1
2
3
4
5
6
<p onclick="handleClick(this)">如果你点我,我就会消失。</p>
<script>
function handleClick(domObj) {
console.log(domObj);
}
</script>

  • mongosh:打开命令行

  • 进入数据库:use DBname。展示:show dbsshow collections

  • mongoimport mongoexport备份与恢复集合(collection)

    共同的相关配置:-d DBname -c COLname -h IPaddress:PORTname

    从filename导入:mongoimport [config] filename

    filename:mongoexport [config] -o filename

    导入数据要避免与原来的数据重复,先删除集合db.COLname.drop() 再mongoimport

  • MongoDB 数据库备份(mongodump)与恢复(mongorestore)

  • 命令行中打印变量print VARIABLE

  • 使用javascipt的数组迭代方法forEach map
    这样可以方便的操作字段名(field),如字段重命名、字段合并

1
2
3
4
5
6
7
8
9
10
11
12
db.getCollection('spaces').find({}).forEach(function(x) {
if(x.in_company) {
x.in_company = x.in_company.map(function(ele, i) {
return {
name: ele,
website: x.in_company_url ? x.in_company_url[i] : null,
}
});
delete x.in_company_url;
db.spaces.save(x);
}
})
  • 加入表的关联:mongoose字段加入ref属性,查询时加入populate方法。

数据库操作

  • db.COLname.save()包含_id则为修改文档,不包含则与db.COLname.insert()功能相同

  • 查询时注意String(‘1’)与Number(1)的区别,在mongoose的保存save与更新update操作中,定义好Schema的字段类型后,则数字与字符串没有区别。

  • 查询不存在字段名或者字段的值为nulldb.COLname.find({"FIELD": null})

    相应的查询字段存在并且值为nulldb.COLname.find({"FIELD": {"$in":[null],"$exists":true}})

    查询存在该字段的文档{$exists: true}

  • 文档中的字段存储数组/对象时的查询:在文档{"fruits" : [ "apple", "pear", "orange" ] }

    字段的值为数组:

    找到数组中包含值:find({"fruits":"apple"})

    数组中包含多个值:find({"fruits":{"$all":["apple","banana"]}})

    数组中某个索引为某个值:find({"fruits.1":"orange"})

    精确查询,要求值相同并且顺序一致:
    find({"fruits":["apple","orange","pear"]})

    字段的值为对象数组时:使用精确匹配时,只会找出字段的值相等并且顺序一致的文档。

    要求包含某些键值对,注意与字段的值为对象时查询的区别:

    find({ "name.first":"joe", "name.middle":"bush" })

安全策略

设置用户权限

  • mongod --auth开启权限认证,再加入用户分配权限
  • TLS/SSL传输加密
  • 数据库定时备份
  • 不使用mongodb默认端口,防止端口扫描
  • 不需要公网连接时,bind_ip只允许本地访问

mongoose

mongoose的model名称为首字母大写时,存到mongodb时会自动首字母小写

mongodb版本6安装

安装MongoDB Community Server

安装MongoDB Shell

  • React.Children.map(this.props.children, () => { …… })
  • 改变state不使用push方法而是setState
  • ES6语法const props = { ...this.props };
  • 组件自定义背景,在父组件位置设置style属性,然后在子组件里面继承style属性;
  • setState是异步的,不会马上更新state。setState有callback函数
  • react-router的onEnter设置路由权限
  • 使用div模拟textarea:属性contentEditable="plaintext-only"onInput={this.emitChange}this.inputRef.innerHTML获取输入内容。
1
2
3
4
5
6
7
<div
className="input_content"
onInput={this.inputChange}
contentEditable="plaintext-only"
ref={(inp) => { this.inputRef = inp }}
onKeyDown={this.onKeyDown}
/>

新版ref写法ref={this.inputRef}

  • 键盘事件
1
2
3
onKeyDown = (e) => {
console.log(e.key);
}

状态提升

你一定听说过变量提升,函数提升,那么状态提升是什么呢?

首先你得了解双向绑定和单向数据流,双向绑定中,数据可以在不同的组件之间实现共享,这样做的确有很大的好处,但是在react中,不推荐使用双向绑定,而是使用状态提升的方式。

状态提升:state推崇单向数据流,数据从父组件通过props流向子组件,如果你在子组件中,需要修改state来和其他子组件共享数据更新,你需要使用回调函数给使数据更新给父组件,然后从父组件流向其他的子组件,这样做是保证数据有单一的来源。

如果子组件和子组件之间任意共享数据,那么,后期维护会比较痛苦,特别是找bug的时候。

看一个状态提升的例子吧。

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
class Child extends React.Component {
constructor(props) {
super(props);
}
handleChange = (e) => {
this.props.upDateValue(e.target.value);
}
render() {
const {name, value} = this.props;
return (
<div>
<p>{name}:</p>
<input
value={value}
onChange={this.handleChange}
/>
</div>
);
}
}

class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {value: '', name: ''};
}
upDateValue = (value) => {
this.setState({value: value})
}
render() {
const {value} = this.state;
return (
<div>
<Child name="组件1" value={value} upDateValue={this.upDateValue} />
<Child name="组件2" value={value} upDateValue={this.upDateValue} />
</div>
);
}
}
ReactDOM.render(
<Demo />,
document.getElementById('root')
);
- 传递属性给子组件

const childrenWithProps = React.Children.map(this.props.children,
child => React.cloneElement(child, {
equityRate: this.publishTasks,
}),
);

this.context

  • this.context用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//在父组件中包含方法
getChildContext() {
return {
USER: this.state.USER,
};
}
Parent.childContextTypes = {
USER: PropTypes.object,
};
//在子组件中
Child.contextTypes = {
USER: PropTypes.object,
};
constructor(props, context)

Atom快捷键

  • Ctrl+shift+m预览markdown

  • string操作不改变原string,只会返回新string。Buffer只改变原Buffer。
  • bin => dup
1
2
var dup = new Buffer(bin.length);
bin.copy(dup);
  • 附件上传
1
2
3
4
5
6
7
8
9
10
11
12
const uploadFile = (req, res, next) => {
//生成multiparty对象,并配置上传目标路径
var form = new multiparty.Form({uploadDir: './public/files/'});
//上传完成后处理
form.parse(req, function(err, fields, files) {
var inputFile = files.file[0].path;
console.log('inputFile', inputFile);
res.writeHead(200, {'content-type': 'text/plain;charset=utf-8'});
res.end(inputFile);
//res.end(util.inspect({files: inputFile}));
});
};
  • 实现文件下载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
router.get('/file/:fileName', function(req, res, next) {
var fileName = req.params.fileName;
var filePath = path.join(__dirname, fileName);
var stats = fs.statSync(filePath);
if(stats.isFile()){
res.set({
'Content-Type': 'application/octet-stream',
'Content-Disposition': 'attachment; filename='+fileName,
'Content-Length': stats.size
});
fs.createReadStream(filePath).pipe(res);
} else {
res.end(404);
}
});

前端<a>标签加上download属性后就可以下载了

服务器操作

  • pm2 list
  • pm2 restart 1
  • pm2 start <path/to/app.js>

Yarn

  • yarn add [package]
  • yarn add [package]@[version]
  • yarn add [package]@[tag]
  • yarn upgrade [package]
  • yarn remove [package]
  • yarn install

  • Boolean && 变量
  • Boolean || 变量可以用来设置默认值,如果 user.name 是 undefined、null、0、’’(空字符串)或 false 等 falsy 值,name 将被设置为’Guest’。空值合并运算符(??)是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
  • a.indexOf(b)a为字符串或者数组
  • a.toFixed(2)a类型为number,保留小数
  • toString()可以判断对象的类型。Object.prototype.toString.call(<value>)
  • -a可以将a转化为number类型
  • 正则表达式//gi,g表示全局搜索,i表示忽略大小写
  • js不支持负向零宽断言/(?<=Jack)Sprat/(ES2018后支持)
  • Math.floor()向下取整,Math.ceil()向上取整,Math.round()四舍五入。
  • arr.sort(func):改变原数组。func返回值为负数则a,b顺序不变。(从小到大排序,则a<b并且返回负值,则返回a-b;从大到小排序,则a>b并且返回负值,则返回b-a
  • reverse()改变原数组
  • substr() 方法返回一个字符串中从指定位置开始到指定字符数的字符。
    不改变原数组,字符串
    str.substr(start[, length])
  • Array.prototype.slice()
    String.prototype.slice()
    slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
  • Array.prototype.splice(start[, deleteCount[, item1[, item2[, ...]]]])
    splice() 方法通过删除现有元素或者原地添加新的元素来修改数组,并以数组形式返回删除的元素。此方法会改变原数组。
  • Array.forEach(arguments, func())对非数组序列进行forEach处理
  • Array(<len>).fill(<value>) 填满数组
  • 数组操作: shift(),unshift(),pop(),push()。改变原数组。
  • Array.prototype.join(<string>)合并为字符串。String.prototype.split(''):返回分割成的数组。
  • this总是指向函数的直接调用者(而非间接调用者),在DOM事件中,this指向定义这个事件的DOM对象;
  • t=setTimeout(fun(), N毫秒);clearTimeout(t)t=setInterval();clearInterval(t)
  • async与await
1
2
3
4
5
6
var start = async function () {
for (var i = 1; i <= 10; i++) {
console.log(`当前是第${i}次等待..`);
await sleep(1000);
}
};
  • EventTarget.addEventListener()
  • e.preventDefault();
  • e.stopPropagation()阻止捕获或冒泡阶段中当前事件的进一步传播

对象处理

  • Object.keys(obj)得到对象的可枚举属性
  • delete Obj.prop删除对象属性
  • 字符串与对象的转换:JSON.stringify(json)JSON.parse(string)。Array也是Object类型
  • 字符串变量d用作对象属性名:{ [d]: !this.state[d] }

作用域

  • if块级作用域在ES5与ES6中不同。用 let 或 const 声明是块级作用域:用一对花括号(一个代码块)创建出来的作用域
  • const a = func; 与function a(){}的变量提升方式不同;
  • for循环中let 与var i = 0,在函数中不同

精度:使用 64 位双精度浮点型来表示

0.1 和 0.2 在二进制中是无限循环小数

原型继承

  • 对象的constructor属性指向它的构造函数。对象的__proto__属性指向上一级的原型对象。构造函数的prototype等于其生成对象的getPrototypeOf(__proto__)。
  • 必须显式地设置原型才能确保动态的继承,将B设置为A的原型链: A.prototype = new B;
  • 将构造器B属性传给A作为A的自身属性
1
2
3
4
function A (a, b) {
B.call(this, c, d);
this.machine = mach || "";
}
  • A为函数:A.prototype={ constructor: A, __proto__: 基本prop }

Web APIs

  • 在chrome中加入断点:在源码中加入debugger
  • 前端全局对象window,node.js全局对象global。全局对象可以用来设置全局变量window.abc
  • window.location获取当前页面网址信息,可进行页面跳转
  • fetch跨域加上{ mode: ‘no-cors’ },response类型为opaque,status为0。或者使用fetch-jsonp
  • 赋值localStorage.abc = string,数字存入localStorage后变为string
  • URLSearchParams
  • es6 array新方法
0%