john's tech blog

hope is coming


  • 首页

  • 标签

  • 归档

javascript_replace

发表于 2017-04-21 | 更新于 2019-05-07

javascript replace

在看angular源码时 有这么一个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14

//. 匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
//感觉应该是/([\:\-\_])+(.)/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;

function camelCase(name) {
return name.
replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset,all) {
return offset ? letter.toUpperCase() : letter;
//all 为字符串本身
}).
replace(MOZ_HACK_REGEXP, 'Moz$1');
}

怎么使用呢?

1
2
3
4
5
6
var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;

var result = 'ng-app'.replace(PREFIX_REGEXP, '');

console.log(camelCase(result));
//输出ngApp

第二个参数为函数:

在ECMAScript3推荐使用函数方式,实现于JavaScript1.2.当replace方法执行的时候每次都会调用该函数,返回值作为替换的新值。

函数参数的规定:

第一个参数为每次匹配的全文本($&)。
中间参数为子表达式匹配字符串,个数不限.( $i (i:1-99))
倒数第二个参数为匹配文本字符串的匹配下标位置。
最后一个参数表示字符串本身。

参考资料:
js的replace函数入参为function时的疑问
JavaScript 函数replace揭秘

scala_bytestring

发表于 2017-04-21 | 更新于 2019-05-07

scala bytestring

上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

object TestByteString extends App {


implicit val byteOrder: ByteOrder = ByteOrder.BIG_ENDIAN
val bsb = new ByteStringBuilder();
bsb.append(ByteString ( int2Bytes(2) ));

val bs = bsb.result();

println(bs.iterator.getInt)

def int2Bytes(value: Int): Array[Byte] = {

Array(((value >> 24) & 0xFF).toByte, ((value >> 16) & 0xFF).toByte, ((value >> 8) & 0xFF).toByte, (value & 0xFF).toByte)
}
}

我们来看看ByteIterator的getInt方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
def getInt(implicit byteOrder: ByteOrder): Int = {
if (byteOrder == ByteOrder.BIG_ENDIAN)
((next() & 0xff) << 24
| (next() & 0xff) << 16
| (next() & 0xff) << 8
| (next() & 0xff) << 0)
else if (byteOrder == ByteOrder.LITTLE_ENDIAN)
((next() & 0xff) << 0
| (next() & 0xff) << 8
| (next() & 0xff) << 16
| (next() & 0xff) << 24)
else throw new IllegalArgumentException("Unknown byte order " + byteOrder)
}

相当于遍历byte数组再左移再用或运算

angular_scope_apply

发表于 2017-04-18 | 更新于 2019-05-07

angular scope apply方法

在bootstrap函数中我们会调用scope.$apply函数,代码如下:

1
2
3
4
5
6
7
8
9
10
var injector = createInjector(modules, config.strictDi);
injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
function bootstrapApply(scope, element, compile, injector) {
scope.$apply(function() { //rootScope
element.data('$injector', injector);
compile(element)(scope);
});
}]
);
return injector;

我们来看看scope.$apply函数内部是如何调用的:

$apply函数是在$rootScopeProvider中定义的:

$apply函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$apply: function(expr) {
try {
beginPhase('$apply');
try {
return this.$eval(expr);
} finally {
clearPhase();
}
} catch (e) {
$exceptionHandler(e);
} finally {
try {
$rootScope.$digest();
} catch (e) {
$exceptionHandler(e);
throw e;
}
}
}

$eval函数

1
2
3
$eval: function(expr, locals) {
return $parse(expr)(this, locals);
}

$parse函数

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
function $parse(exp, interceptorFn, expensiveChecks) {
var parsedExpression, oneTime, cacheKey;

expensiveChecks = expensiveChecks || runningChecksEnabled;

switch (typeof exp) {
case 'string':
exp = exp.trim();
cacheKey = exp;

var cache = (expensiveChecks ? cacheExpensive : cacheDefault);
parsedExpression = cache[cacheKey];

if (!parsedExpression) {
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
oneTime = true;
exp = exp.substring(2);
}
var parseOptions = expensiveChecks ? $parseOptionsExpensive : $parseOptions;
var lexer = new Lexer(parseOptions);
var parser = new Parser(lexer, $filter, parseOptions);
parsedExpression = parser.parse(exp);
if (parsedExpression.constant) {
parsedExpression.$$watchDelegate = constantWatchDelegate;
} else if (oneTime) {
parsedExpression.$$watchDelegate = parsedExpression.literal ?
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
} else if (parsedExpression.inputs) {
parsedExpression.$$watchDelegate = inputsWatchDelegate;
}
if (expensiveChecks) {
parsedExpression = expensiveChecksInterceptor(parsedExpression);
}
cache[cacheKey] = parsedExpression;
}
return addInterceptor(parsedExpression, interceptorFn);

case 'function':
return addInterceptor(exp, interceptorFn);

default:
return addInterceptor(noop, interceptorFn);
}
}

addInterceptor函数

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
//interceptorFn传空就直接返回parsedExpression
function addInterceptor(parsedExpression, interceptorFn) {
if (!interceptorFn) return parsedExpression;
var watchDelegate = parsedExpression.$$watchDelegate;
var useInputs = false;

var regularWatch =
watchDelegate !== oneTimeLiteralWatchDelegate &&
watchDelegate !== oneTimeWatchDelegate;

var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) {
var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs);
return interceptorFn(value, scope, locals);
} : function oneTimeInterceptedExpression(scope, locals, assign, inputs) {
var value = parsedExpression(scope, locals, assign, inputs);
var result = interceptorFn(value, scope, locals);
// we only return the interceptor's result if the
// initial value is defined (for bind-once)
return isDefined(value) ? result : value;
};

// Propagate $$watchDelegates other then inputsWatchDelegate
if (parsedExpression.$$watchDelegate &&
parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
fn.$$watchDelegate = parsedExpression.$$watchDelegate;
} else if (!interceptorFn.$stateful) {
// If there is an interceptor, but no watchDelegate then treat the interceptor like
// we treat filters - it is assumed to be a pure function unless flagged with $stateful
fn.$$watchDelegate = inputsWatchDelegate;
useInputs = !parsedExpression.inputs;
fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];
}

return fn;
}

参考资料:
AngularJs学习笔记–Scope

angular_$provide

发表于 2017-04-17 | 更新于 2019-05-07

angular provide源码解析

在createInjector中会调用loadModules方法,loadModules方法中调用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//遍历modulesToLoad数组
forEach(modulesToLoad, function(module) {
if (isString(module)) {
moduleFn = angularModule(module);
runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
runInvokeQueue(moduleFn._invokeQueue);
//像module.service时加入的service ,那么需要把这些service加入prividerCache
runInvokeQueue(moduleFn._configBlocks);
} else if (isFunction(module)) {
runBlocks.push(providerInjector.invoke(module));
} else if (isArray(module)) {
// $provide.value('$rootElement', element);
//为undefined
//invoke里会调用function
runBlocks.push(providerInjector.invoke(module));
} else {
assertArgFn(module, 'module');
}
}

还记得bootstrap中调用是怎么样的么?

1
2
3
4
5
modules = modules || [];
//unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
modules.unshift(['$provide', function($provide) {
$provide.value('$rootElement', element);
}]);

那么就会先调用providerInjector.invoke然后再push到runBlocks中,$provide定义如下:

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
function valueFn(value) {return function valueRef() {return value;};}

function createInjector(modulesToLoad, strictDi) {
var providerCache = {
$provide: {
provider: supportObject(provider),
factory: supportObject(factory),
service: supportObject(service),
value: supportObject(value),
constant: supportObject(constant),
decorator: decorator
}
};

function provider(name, provider_) {
assertNotHasOwnProperty(name, 'service');
if (isFunction(provider_) || isArray(provider_)) {
//先实例化
provider_ = providerInjector.instantiate(provider_);
}
if (!provider_.$get) {
throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
}
return providerCache[name + providerSuffix] = provider_;
}

function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}

function value(name, val) { return factory(name, valueFn(val), false); }
}

看instantiate方法:

1
2
3
4
5
6
7
8
9
function instantiate(Type, locals, serviceName) {
// Check if Type is annotated and use just the given function at n-1 as parameter
// e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);
var args = injectionArgs(Type, locals, serviceName);
// Empty object at position 0 is ignored for invocation with `new`, but required.
args.unshift(null);
return new (Function.prototype.bind.apply(ctor, args))();
}

linux_vi2

发表于 2017-04-12 | 更新于 2019-05-07

linux vi撤销

在vi中按u可以撤销一次操作

u 撤销上一步的操作

Ctrl+r 恢复上一步被撤销的操作

vi中的撤销与重做

1…252627…47

John

232 日志
43 标签
GitHub Twitter
欢迎关注我的公众号:沉迷Spring
© 2023 johnwonder
由 Hexo 强力驱动 v3.2.0
|
主题 – NexT.Pisces v7.1.1
|
0%