Giter VIP home page Giter VIP logo

til's Introduction

前置说明: 本库记录自己前端所学, 内容在对应的文件夹下,相当于个人博客,可以在gitbook中预览

目录


前端

学习之道

面试题库

前端工具

前端学习链接

w3c
dom
css&html
js
images
ts
flex
react
blog
性能相关
懒加载
网站性能

浏览器

前端安全

前端新手学习库

后端

ruby

推荐书籍

til's People

Contributors

guoslxx avatar xhsblog avatar xiaohesong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

til's Issues

[每日见闻-2017-08-09]ss配置系列

客户端配置

ubuntu

  1. 安装相关包
sudo apt-get install python-pip
sudo pip install shadowsocks
# sudo vim /ss-conf.json
{
  "server":"remote ip",
  "server_port":你的端口,
  "local_address":"127.0.0.1",
  "local_port":1080,
  "password":"password",    
  "timeout":600,
  "method":"aes-256-cfb"
}

可以通过sslocal -c /ss-conf.json来启动。

每次这样启动比较麻烦,加入开机自动启动.

  • 添加自动动脚本
# sudo vim /home/shadowsock.sh
#!/bin/bash
sslocal -c /ss-conf.json
  • 加入自启动
# sudo vim /etc/rc.local
nohup bash /home/shadowsock.sh > /home/ss-log.txt &
# 上面这个加在`exit 0`之前
sudo cp /usr/local/bin/sslocal /bin/
sudo reboot

服务端配置

ubuntu

  1. 安装相关的包
sudo apt-get update
sudo apt-get install python-pip
sudo pip install shadowsocks

不出意外,会安装成功了这里.然后添加一个配置文件
sudo vim shadowsocks-conf.json:

{
  "server":"0.0.0.0",
  "server_port":8888,
  "local_address":"127.0.0.1",
  "local_port":1080,
  "password":"这里是你的链接ss的密码",    
  "timeout":600,
  "method":"aes-256-cfb"
}

上面就是对应的配置文件,服务端配置好之后,启动shadowsocks:

sudo ssserver -c shadowsocks-conf.json -d start

reduce: 实现一个reduce方法

今天无意间看到一个面试题有问到如何实现一个reduce函数,额,花了点时间算是写下来了。写这个方法的前提是了解这个api。

  • 默认初始值
    这个就是对应的reduce的第二个参数。
    • 如果有这个参数,那么这个参数将作为reduce的第一个参数(函数)的第一个参数,(函数)的第二个参数是数组的第一个参数;
    • 如果没有这个,那么reduce函数的第一个参数(函数)的第一个参数是数组的第一个元素,(函数)的第二个参数就是数组的第二个元素。

所以,reduce函数的第一个参数(函数)的第三个参数(索引), 就是根据reduce函数的第二个参数在数组中的牵引做的判断。

好了,我们知道了这个reduce函数的api之后,我们尝试来写个:

const array = [11, 22, 33]
const reducer = (arr, fn, initValue) => {
  if(!Array.isArray(arr)) throw new Error('First Argument Must Be Array')
  if(typeof fn !== 'function') throw new Error('Second Argument Must Be Function');
  
  var i = initValue ? 0 : 1 // 因为如果不存在initValue, 数组第一个就得补上,所以索引从1开始。和下面的赋值操作的顺序不可以对调!
  initValue = initValue ? initValue : arr[0] //因为存在init的话,第一个就是init, 不存在,第一个就是数组的第一个元素
  for(i; i < arr.length; i++){
    initValue = fn(initValue, arr[i], i, arr)
  }
  
  return initValue
} 
reducer(array, (sum, i) => sum + i)

柯里化函数

之前有写过一篇文章,是说柯里化函数和函数组合, 看完之后真是大受脾益,尤其是在看redux源码的时候,就感觉很顺通。

今天上午看了下简书,发现了一个被面试到的问题,思考了下。问题是这样的:

函数闭包与柯里化(让手写一个函数完成求和操作,func(1)(2)(3)、func(1,2)(3)和func(1,2,3)都能保证可以正常求和)

function add(...args) {
  return args.reduce((total, item) => total = total + item, 0)
}

function func(fn){
  return (length) => (...args) => (length - args.length) ? func(fn)(length).bind(null, ...args) : fn(...args)
}
add3 = func(add)(3)
add3(1)(2)(3)
add3(1,2)(3)
add3(1,2,3)

上面的func看起来有些怪怪的, 有这个func(fn)(length),那么我们来改下下

function func(fn){
  return (length) => varFun =  (...args) => (length - args.length) ? varFun.bind(null, ...args) : fn(...args)
}

[每日见闻-2017-06-30]使用Rails构建Api.

Rails的框架太重,很多人以Api为主的项目,都会选择其他的框架.sinatra,rabl,grape..诸如此类的框架.
其实用Rails也还是可以的.直接controller继承自ActionControll::Metal.仅仅加载用到的模块的模块.
参考这里

你也是17年才接触前端的吗

感谢库主的分享,仓库内容挺细致的。
不过我有个问题,看你这个仓库貌似是建于17年中下旬。难道你学前端两年不到吗?

[每日见闻-2017-07-03]Rails flash,Middleware和Metal的区别, 重构Routes的方法

Rails flash

  • Rails的消息提示有notice, alert,其实还可以追加类型.
class ApplicationController < ActionController::Base
  add_flash_types :warning, :success, :danger
end
  • notice的区别
# 1. 新建失败时,可以
 render 'new', flash.now[:notice] = '嘻嘻嘻' 
# 2. 新建成功时,可以
redirect_to xx_path, flash['notice']= '嘻嘻嘻'

Middleware Metal的区别

Middleware 是 Action Dispatch 实现的,而 Metal 是 Action Controller 实现的。
Middleware 是在请求进入 action 之前,而 Metal 是在请求进入 action 之后。
Middleware 需要的环境是 env,作用的是 app;而 Metal 增强组件需要的环境是 Controller & action,目的主要是对请求做处理,并响应。

重构路由

-. 首先得知道路由里 scopenamespace的区别.之前倒是使用namespace比较多,对于scope知之甚少.

scope as: 'admin', path: '/admin', module: 'admin' do
  #some resources
end

# 等价于

namespace :admin do
  # some resources
end

-. 重构路由
有些项目是api和页面共存的. 大量充斥着重复的代码.

# 重构前
namespace :a do
  resources :users
  resources :orders
end

namespace :b do
  resources :users
  resources :orders
end

# 重构后
concern :base do
  resources :users
  resources :orders
end

namespace :a do
  concerns :base
end

namespace :b do
  concerns :base
end

来看看D大神的说法

[每日见闻-2017-07-27]Rails细节的性能对比

  • method argument
def hello(foo: nil, bar: nil)
end
10_000.times { hello(foo: 1, bar: 2) }

# Runtime => 10.354 ms
def hello(options = {})
  foo, bar = options[:foo], options[:bar]
end
10_000.times { hello(foo: 1, bar: 2) }
# Runtime => 5.064 ms
  • obj.method VS obj attr_reader
class Foo
  def initialize(val)
    @val = val
  end

  def val
    @val
  end
end

object = Foo.new("bar")
100_000.times { object.val }
# Runtime => 9.284 ms
class Foo
  def initialize(val)
    @val = val
  end

  attr_reader :val
end

object = Foo.new("bar")
100_000.times { object.val }
# Runtime => 6.966 ms

一些不错的js题

输出内容系列

输出什么?

function getPersonInfo(one, two, three) {
  console.log(one);
  console.log(two);
  console.log(three);
}

const person = "Lydia";
const age = 21;

getPersonInfo`${person} is ${age} years old`;

是不是大吃一惊,哈哈。这个细节还真是没有注意到。

惰性函数

今天看到一篇文章中有提到 惰性函数 。感觉很新奇,去查了下,发现就是自己调用自己。

可以让你只在第一次的时候调用你需要处理的函数,后面可以直接使用函数。

var foo = function() {
  console.log('你会发现我只出现一次哦,不管你调用几次')
  foo = function() {
    console.log('嘻嘻,我出现了哦')
  }
  foo()
}

foo() // 你会发现我只出现一次哦, 不管你调用几次; 嘻嘻,我出现了哦
foo() //嘻嘻,我出现了哦

还挺有意思的,留下个问题,你觉得这个是因为啥,为啥会出现上面的情况?

没事写了个双向绑定(defineProperty&&Proxy)

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>测试</title>
</head>
<body>
  Name: <input class='input' name='input'/>
  add: <button class='button'>+</button>
</body>
<script>
let input = document.querySelector('.input')
let button = document.querySelector('.button')
let num = 0

button.addEventListener('click', function(){
  num++
  input.value = num
})

let proxy = new Proxy(input, {
  set(trapTarget, key, value, receiver) {
    if (isNaN(value)) {
      throw new TypeError("Property must be a number.");
    }

    return Reflect.set(trapTarget, key, value, receiver);
  }
})

Object.defineProperty(input, 'value', {
  enumerable: true,
  value: '',
  get: function () {
    console.log('get this value is', this._value)
    return this._value
  },
  set: function (val) {
    console.log('set this value is', val)
    this._value = val
  }
})


</script>
</html>

[每日见闻-2017-07-20]关于self的小细节

  • self在当前的initialize中直指当前的实例对象
class Foo
  def initialize(x)
    self.c x
  end
 
  def c(x)
    puts "c的参数是#{x}"
  end
end
f = Foo.new(1)
  • 带给我的感觉
    self在很大程度上类似.都是指定当前的实例.给我的感觉就是
self == @
!self.eql?(@)

类似于coffee js

this && @

例如:

class Foo
  attr_accessor :name
  def initialize(x)
    @name = "wo"
  end
end

class Foo
  attr_accessor :name
  def initialize(x)
    self.name = "wo"
  end
end

f = Foo.new(3)
puts f.name

再比如

class A
  @num = 8
  def show
    puts @num
  end
end

class B < A
  def initialize
    @num = 3
  end
end

b = B.new
b.show

bind, 函数的第二个参数会输出什么?

今天看到一个地方有误解,自己试了下,感觉挺不错。

你觉得下面的这个consolesaga会输出什么?

function run({name, age}, saga, ...options){
  console.log('name is', name, 'saga is', saga)
}
let boundRun = run.bind(null, {name: 'xiaohesong', age: 18})

function *rootSaga() {
  yield 'i am a generator function'
}

boundRun(rootSaga)

js到底是解释型语言还是编译型语言?

之前一直没有怎么考虑过这个问题,只是貌似听说过js是一个解释型语言,不需要编译。
为什么突然扯到这个类型上面呢,主要是因为在群里看到争论,于是搜索了下。

看到一篇帖子,说Is Javascript a compiled language?, 他重复说了很多次, 以及确定js就是编译型语言,很遗憾的是,下面的评论打脸了,很确定的告诉他,js不是一个编译型语言,编译的子集并不能说明语言本身是一个编译型的语言。

然后我们在quora里也可以看到说js是一个解释型语言.

这里面有两个回答不错,其中有段话很直接:

Bottom Line :

Javascript is interpreted. As in the language has been implemented in that fashion as because it was >supposed to be used on the browser platform. And since interpreted language is not a spec, browser >vendors have modified it for performance.
很直接的说明了,由于解释型语言不是规范,所以浏览器供应商便更改了他的性能。

我们再来看看stack exchange的一个问答,Is JavaScript interpreted by design?

The semantics of statements and expressions in the language are defined in terms of completion >specification which are trivially implemented in an interpreter, but the specification does not require >that.

意思就是 语言中语句和表达式的语义是根据完成规范定义的,这些规范在解释器中通常可以实现,但规范并不要求这样。

并且在语言定义的时候也没有出现解释器的说明, EcmaScript语言极客们通常使用术语“ES解释器”来指代EcmaScript的实现,但规范不使用该术语。语言概述特别描述了与解释器无关的术语:

ECMAScript is object-based: basic language and host facilities are provided by objects, and an ECMAScript program is a cluster of communicating objects.
可以发现,并没有解释器这个词眼出现。

另外可以参考下ECMAScript engines, 有对应的编译器和解释器,这都是实现规范的一种方法,所以你不需要这些也可以,只是有实现的差异化。

所以说,js不是编译型语言,他是解释型的语言。但是也看情况,就语言本身而言,不存在情况。
他本身就是一个解释型的语言,以至于解释器也不需要。

[每日见闻-2017-08-29]es6

  • module
    module.exports的作用等同于export default
module.exports = {
  foo: 'hello'
};

// 等同于
export default {
  foo: 'hello'
};

[每日见闻-2017-07-26]-ssh相关-配置远程服务器别名

别名服务器

cd ~/.ssh
# vim config
Host nickname #你的别名
User user #你的远程用户
HostName 192.168.2.2 #你的远程ip
Port 22 #你的远程端口号
ForwardAgent yes
ServerAliveInterval 60 #断开时间

再运行之前,还需要把ssh添加到远程服务器

ssh-keygen #如果没有 ssh
ssh-copy-id user@ip

然后就可以别名登录远程服务器了.

ssh nickname

禁止root登录ssh

# sudo vim /etc/ssh/ssh-config
Port 12345 #可以设置你想要的端口
PermitRootLogin no # 禁止root登录

js的map和forEach到底哪个速度快?

今天看到一篇文章,一个大神写的。可以看Speed Considerations这个地方,他说他那里测试是mapforEach快不少。

image

我觉得不太可能,毕竟map是返回一个新的数组呀。

//example.js
mapTag = "Map Spent Time is"
eachTag = "Each Spend Time is"
mapArr = eachArr = [...Array(1000000)]

console.time(mapTag)
mapArr.map((i, index) => {
  return index * 2
})
console.timeEnd(mapTag)

console.time(eachTag)
eachArr.forEach((i, index) => {
  return eachArr[index] = index * 2
})
console.timeEnd(eachTag)

从上面这个例子可以发现不是这样的。

不对呀,jsperf应该不会出问题的。难道是forEach有提升吗?找了下,没有找到相关的资料,值看到了说17年八月初forEach有提升十倍,那也不对呀,上面的文章提到的是2017年12月份。

jsperf的工作方式

比较好奇啊,这是为啥呐。

you dont known js - trick && skill

这里记录一些you don't know js提出的一些小细节,小技巧。

章: types&&grammer 点击查看此章各小节

values

  • isNaN
    测试传入的东西要么不是number,要么是number。但是这样是严谨的吗?
var a = 2 / "foo";
var b = "foo";

a; // NaN
b; // "foo"

window.isNaN( a ); // true
window.isNaN( b ); // true -- ouch!

"foo"实际上不是一个number,但它绝对不是NaN值!
显然,这是不合理的,foo并不是一个NaN。所以es6添加了Number.isNaN, 就是对这个问题(bug)的补充。

if (!Number.isNaN) {
	Number.isNaN = function(n) {
		return (
			typeof n === "number" &&
			window.isNaN( n )
		);
	};
}

var a = 2 / "foo";
var b = "foo";

Number.isNaN( a ); // true
Number.isNaN( b ); // false -- phew!

可以发现,首先确认他是不是数字类型,然后再进行isNaN判断。

Coercion, 点击查看详细内容

  • ~
const arr = ['ni', 'wo', 'ta']
//使用~之前
if(arr.indexOf('js') === -1){
  //不存在
}
//使用~之后
if(!~arr.indexOf('js')){
  //不存在
}

记住: ~操作符类似于-(x + 1)

grammer 点击查看详细内容

  • ||&&优先级

先自己问自己一把,||&&的哪个优先级更高?
在很长一段时间里,我认为这两个优先级是一样的,实则不然。
看下面代码:

false && true || true // ??
(false && true) || true // ??

通过上面的例子,我想你可以知道优先级高低的答案了。
当然,你可以参考MDN - Operator Precedence

考虑下面这个例子会输出什么?

var a = 42;
var b = "foo";
var c = false;

var d = a && b || c ? c || b ? a : c && b : a;

d;		// ??

上面例子具体的可以看这里 运算符优先级问题

章:scope&&closures 点击查看各小节

what is scope 点击查看详细内容

ReferenceErrorTypeError区别

  • ReferenceError
    这个是作用域解析失败相关而抛出的异常

  • TypeError
    作用域解析成功,但试图对结果执行非法/不可能的操作。

lexical scope 点击查看详细内容

  • eval

    他会修改现有的词法作用域(非严格模式)

     function run(str){
         eval(str)
          console.log(yourName)
     }
     run("var yourName = 'xhs'")

    然后你可以在里面试试严格模式。

  • with
    创建一个 全新的词法作用域

    function foo(obj) {
    	with (obj) {
    		a = 2;
    	}
    }
    
    var o1 = {
    	a: 3
    };
    
    var o2 = {
    	b: 3
    };
    
    foo( o1 );
    console.log( o1.a ); // 2
    
    foo( o2 );
    console.log( o2.a ); // undefined
    console.log( a ); // 2 -- Oops, leaked global!

    可以看见,LHS查找不存在,就直接到了上一层。

章:this&object prototypes 点击查看此章各小节

this指向, 点击查看详细内容

  • 默认绑定 🛫
  • 隐式绑定 🛩
  • 显示绑定🛩
  • new绑定🛩
    绑定关系是按照上面依次增强 🛩

Objects 点击查看详细内容

  • property
    对于熟悉描述,在之前有做过小小的对象属性总结
    这里说下enumerable 是啥:就是在迭代(循环遍历)中包含。
    可以检查是否为enumerable,在对象属性总结那里有提到,现在来说下另外一个方法propertyIsEnumerable
var myObject = { };

Object.defineProperty(
	myObject,
	"a",
	{ enumerable: false, value: 2 }
);
myObject.propertyIsEnumerable( "a" ); // false

propertyIsEnumerable(..)测试给定的属性名称是否 直接 存在于对象上,并且也是enumerable:true

Prototypes 点击查看详细内容

a instanceof Foo; // true
  • instanceof的意思:a的整个[[Prototype]]链中,Foo.prototype任意指向的对象有没有出现?
Foo.prototype.isPrototypeOf( a ); // true
  • isPrototypeOf(..)的意思是: a整个[[Prototype]]链中,Foo.prototype有没有出现?

isPrototypeOf的实现如下:

function isRelatedTo(o1, o2) {
	function F(){}
	F.prototype = o2;
	return o1 instanceof F;
}

var a = {};
var b = Object.create( a );

isRelatedTo( b, a ); // true

js如何翻转一个字符串&&js如何清除数组

翻转字符串

How to reverse a string in JavaScript

const str = "hello"
str.split('').reverse().join('')
//"olleh"
const str = "hello"
[...str].reduce((prev,next)=>next+prev)
//"olleh"
function reverseString(str){
  const arr = [...str]
  let reverse= "";
  while(arr.length){
     reverse = reverse + arr.pop()
  }
  return reverse
}

清空数组

How to clear an array in javascript

var arr = [1,2,3,4,5,6] 
arr = [ ]
console.log(arr)
//empty array [ ] 
var arr = [1,2,3,4,5,6]
arr.length = 0
console.log(arr)
//empty array [ ]
var arr = [1,2,3,4,5,6]
while(arr.length){
   arr.pop()
}
console.log(arr)
//empty array [ ]

[每日见闻-2017-08-02]sql整理

关于join

  • Left join
select count(distinct store_name) from scores left join stores on scores.scoreable_id = stores.id and scores.scoreable_type = 'Store' where store.status = 0 and scores.user_type=0;
# 这个是查询 所有带有评分的门店,并且门店是营业状态(0)和评分的类型是用户评分(0)
  • Right join
    left join差不多.不过这个是以右表全表为基础进行处理.

  • inner join
    rubyjoins.sql查询中也可以直接使用join,就是inner join

User.joins(:roles).to_sql
# => "SELECT `users`.* FROM `users` INNER JOIN `users_roles` ON `users_roles`.`user_id` = `users`.`id` INNER JOIN `roles` ON `roles`.`id` = `users_roles`.`role_id`"

Inner join 是左右表等价的.

  • includes
A.includes(:bs).where(bs: {name: '#'}).count
# =>
# SELECT COUNT(DISTINCT `bs`.`id`) FROM `as` LEFT OUTER JOIN `bs` ON `bs`.`a_id` = `as`.`id` WHERE `bs`.`name` = '#'

从上面可以发现,left joinincludesleft outer join很像.其实left joinleft outer join类似于joininner join类似的.此处查看

小方法

  • sum
SUM(CASE WHEN num > 0 THEN 1 else 0 END) AS available_times
  • round
ROUND('123.654',2)
# 123.654 取小数后两位
  • GROUP_CONCAT/CONCAT
    返回拼接的字符串. GROUP_CONCAT与group by使用,效果更佳.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.