xiaohesong / til Goto Github PK
View Code? Open in Web Editor NEW本库记录每日所学,README是一些链接;学习是自己的事。
Home Page: http://t.cn/EP1BKKb
本库记录每日所学,README是一些链接;学习是自己的事。
Home Page: http://t.cn/EP1BKKb
今天无意间看到一个面试题有问到如何实现一个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)
<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>
module.exports
的作用等同于export default
module.exports = {
foo: 'hello'
};
// 等同于
export default {
foo: 'hello'
};
加入当前浏览器不支持 Symbol ,恶意模拟了 $$typeof = 0xeac7 能够插入么
这里记录一些you don't know js提出的一些小细节,小技巧。
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
判断。
~
const arr = ['ni', 'wo', 'ta']
//使用~之前
if(arr.indexOf('js') === -1){
//不存在
}
//使用~之后
if(!~arr.indexOf('js')){
//不存在
}
记住: ~
操作符类似于-(x + 1)
||
和&&
优先级先自己问自己一把,||
和&&
的哪个优先级更高?
在很长一段时间里,我认为这两个优先级是一样的,实则不然。
看下面代码:
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; // ??
上面例子具体的可以看这里 运算符优先级问题
ReferenceError
和TypeError
的区别:
ReferenceError
这个是作用域解析失败相关而抛出的异常
TypeError
作用域解析成功,但试图对结果执行非法/不可能的操作。
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查找不存在,就直接到了上一层。
enumerable
是啥:就是在迭代(循环遍历)中包含。enumerable
,在对象属性总结那里有提到,现在来说下另外一个方法propertyIsEnumerable
。var myObject = { };
Object.defineProperty(
myObject,
"a",
{ enumerable: false, value: 2 }
);
myObject.propertyIsEnumerable( "a" ); // false
propertyIsEnumerable(..)
测试给定的属性名称是否 直接 存在于对象上,并且也是enumerable:true
。
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
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 [ ]
之前有写过一篇文章,是说柯里化函数和函数组合, 看完之后真是大受脾益,尤其是在看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)
}
感谢库主的分享,仓库内容挺细致的。
不过我有个问题,看你这个仓库貌似是建于17年中下旬。难道你学前端两年不到吗?
如题
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
# sudo vim /etc/ssh/ssh-config
Port 12345 #可以设置你想要的端口
PermitRootLogin no # 禁止root登录
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
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
输出什么?
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() //嘻嘻,我出现了哦
还挺有意思的,留下个问题,你觉得这个是因为啥,为啥会出现上面的情况?
今天看到一个地方有误解,自己试了下,感觉挺不错。
你觉得下面的这个console
的saga
会输出什么?
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)
看标题那里的网址很长,有工具可以把长链接给缩短。。
short url
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
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
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
ruby
的 joins
.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 是左右表等价的.
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 join
和includes
的left outer join
很像.其实left join
和left outer join
类似于join
和inner join
类似的.此处查看
SUM(CASE WHEN num > 0 THEN 1 else 0 END) AS available_times
ROUND('123.654',2)
# 123.654 取小数后两位
group by
使用,效果更佳.Rails的框架太重,很多人以Api为主的项目,都会选择其他的框架.sinatra
,rabl
,grape
..诸如此类的框架.
其实用Rails也还是可以的.直接controller
继承自ActionControll::Metal
.仅仅加载用到的模块的模块.
参考这里
今天看到一篇文章,一个大神写的。可以看Speed Considerations这个地方,他说他那里测试是map
比forEach
快不少。
我觉得不太可能,毕竟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月份。
比较好奇啊,这是为啥呐。
之前一直没有怎么考虑过这个问题,只是貌似听说过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不是编译型语言,他是解释型的语言。但是也看情况,就语言本身而言,不存在情况。
他本身就是一个解释型的语言,以至于解释器也不需要。
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 是 Action Dispatch
实现的,而 Metal 是 Action Controller
实现的。
Middleware 是在请求进入 action
之前,而 Metal 是在请求进入 action
之后。
Middleware 需要的环境是 env
,作用的是 app
;而 Metal 增强组件需要的环境是 Controller & action
,目的主要是对请求做处理,并响应。
-. 首先得知道路由里 scope
和namespace
的区别.之前倒是使用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
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.