博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html
原题:
大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4个及以上并且想拿高工资的话,请联系我。
- 找出数字数组中最大的元素(使用Match.max函数)
- 转化一个数字数组为function数组(每个function都弹出相应的数字)
- 给object数组进行排序(排序条件是每个元素对象的属性个数)
- 利用JavaScript打印出Fibonacci数(不使用全局变量)
- 实现如下语法的功能:var a = (5).plus(3).minus(6); //2
- 实现如下语法的功能:var a = add(2)(3)(4); //9
以前一直是写.net后台,对js的操作,只是出于dom和ajax之间,对jquery的也只是存在能使用(还不算熟练)
后来在网上找到了tom大叔的javascript系列,发现写的真好.真的是我这种dom能操作,ajax能写,jquery会用.但是希望更深入下去的采纳哦.
于是就花了一些时间来学习博客里的内容.[本文最后回附上javascript系列文章的目录列表]
现在开始答题,用我自己的思路,(因为我本身算不上一个前端,只是偶尔前端忙的时候,我就写一下dom操作,和ajax.jquery里的ajax函数都没记清,还要去查API)
所以出现纰漏和错误的地方还希望大家指出,学习.
第一题:
找出数字数组中最大的元素(使用Match.max函数).
答题思路:首先,我之前没有用过这个函数,js自带的参数提示也是一坨shit,况且弱类型语言,啥玩意都能往里面传,能不能执行就另说.
于是我就百度了一下Match.max函数,发现里面的参数是以Math.max(1,2,3,4,5,6,7) 这种模式.
去掉数组左右小括号里面的"内容"的格式就刚好满足max参数的要求.
于是:
var int_array = [1,2,3,4,5,6];
var str_array ="";
for(var i = 0; i < int_array.length; i++){
str_array += int_array + ",";
}
str_array = str_array.subString(0,str_array.length-1);//这里没有找到一个string内置的去掉特定尾字符的函数(trim(),trimRight)//可能是我参数没调对
eval("Math.max("+str_array+")");
</script>
第一条还算顺利,不算太难.
第二题:转化一个数字数组为function数组(每个function都弹出相应的数字)
答题思路:将一个数字转化成function数组,并且每个函数输出对应的数字.
关键在于"弹出相对应的数字."
明显就是一个闭包的操作.(为什么说"明显",因为我花了2天时间去理解和学习闭包)....
var int_array = [1,2,3,4,5,6,7];
var fn_array = [];
for(var i = 0; i < int_array.length;i++){
var f = (function(lockitem){
return function(){
console.log("当前是函数fn_"+ lockitem +" ---- 对应的数字是:" + lockitem);
}
})(int_array);
fn_array.push(f);
}
for(var j = 0 ; j < fn_array.length;j++){
console.log(fn_array[j]());
}
</script>
第三题:给object数组进行排序(排序条件是每个元素对象的属性个数)
答题思路:首先给一个对象的数组 比如(var obj_array = [{},{},{}]);
然后写一个函数,计算每个对象的属性个数(不包括原型属性),并返回新的对象,这个新的对象有2个属性 var newObj = {obj:obj,count:count};//Obj就是之前计算属性个数的那个对象本身,count是数量
然后在根据count属性排序,并把这个对象的obj属性返回出来.
{
name:"张三"
},
{
name:"张三",
age:25
},
{
name:"张三",
age:25,
address:"湖北武汉"
}
];
function propertyCount(obj){
if(typeof obj !== "object"){
throw new Error("参数类型错误!");
}
var count = 0;
for(var prop in obj){
if(obj.hasOwnProperty(prop)){
count++;
}
}
var obj_instance = {
target:obj,
count:count
}
return obj_instance;
}
//删除数组的指定索引元素
function removeAtIndex(array,index){
array.splice(index,1);
}
var obj_whit_propertyCount = [];
var sort_object = [];
var i_array = [];
for (var x = 0;x < obj_array.length;x++) {
obj_whit_propertyCount.push(propertyCount(obj_array[x]));
i_array.push(propertyCount(obj_array[x]).count);
i_array.sort();
}
for (var s = i_array.length - 1; s >=0;s-- ) {
sort_object.push(returnObj(s+1));
}
console.log(obj_whit_propertyCount);
console.log(sort_object);
function returnObj(count){
for (var q = 0;q < obj_whit_propertyCount.length;q++) {
if(obj_whit_propertyCount[q].count == count){
return obj_whit_propertyCount[q].target;
}
}
}
第三体肯定不是好的思路,不过跌跌撞撞也算是做出来了.
第四题: 利用JavaScript打印出Fibonacci数(不使用全局变量)
我只做出了递归计算,对于打印出1,1,2,3,5,8....这样的数字还没思路,如果读者,请留言告诉我.
if(num == 1 || num == 2){
return 1;
}
return Fibonacii(num-1) + Fibonacii(num-2);
}
console.log(Fibonacii(5)); //第五个数
第五题:实现如下语法的功能:var a = (5).plus(3).minus(6); //2
答题思路:我一开始看到第一个(5),说是实话,真的懵了...怎么会有这么奇特的语法?只有函数调用的时候在会有f()啊!!
后来一想:(1+2)*4 ,(9/3)-1..()就很普通了,不就是一个expression么.
然后在控制台里输出:console.log((5));//返现结果和我预期一样.
于是,就开始琢磨add和minus两个函数.
既然(5)返回就是一个number类型,那我直接就在Number的prototype属性扩展这两个方法好了.(不是老有人老生常谈不要去修改系统的原型对象)
return this + a;
}
Number.prototype.minus = function(num1){
这期将NLog Git版本指向2005-06-09,NLog v0.9 released。这个时候的代码结构升级为这样:
和上期的版本相比,最明显的莫过于原先的Appender全套更名为Target。这期让我们来关注LayoutRender相关的实现。
LayoutRender
首先LayoutRender 继承自抽象类LayoutRenderer
,并且以属性[LayoutRenderer("threadid")]
的方式标注。
[LayoutRenderer("threadid")]
public class ThreadIDLayoutRenderer: LayoutRenderer
LayoutRendererFactory初始化的时候会根据该属性,加载指定程序集下面的所有LayoutRender。
public sealed class LayoutRendererFactory
{
private static TypeDictionary _targets = new TypeDictionary();
static LayoutRendererFactory()
{
Clear();
AddDefaultLayoutRenderers();
}
可以看到静态构造函数里面加载默认Renderers。
private static void AddDefaultLayoutRenderers()
{
AddLayoutRenderersFromAssembly(typeof(LayoutRendererFactory).Assembly, String.Empty);
}
public static void AddLayoutRenderersFromAssembly(Assembly theAssembly, string prefix)
{
InternalLogger.Debug("AddLayoutRenderersFromAssembly('{0}')", theAssembly.FullName);
foreach (Type t in theAssembly.GetTypes())
{
LayoutRendererAttribute[]attributes = (LayoutRendererAttribute[])t.GetCustomAttributes(typeof(LayoutRendererAttribute), false);
if (attributes != null)
{
foreach (LayoutRendererAttribute attr in attributes)
{
AddLayoutRenderer(prefix + attr.FormatString, t);
}
}
}
}
下一步就是解析配置文件中的Layout,一般包含Layout 的配置文件是这样子的:
<nlog>
<targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
<rules>
<logger name='*' minlevel='Debug' appendTo='debug' />
</rules>
</nlog>
这里的layout字符串是: ${basedir} ${message}
,我们希望得到两个Render的数组。
这里layout.cs
里面有个关键的方法
private static LayoutRenderer[] CompileLayout(string s, out int needsStackTrace)
{
ArrayList result = new ArrayList();
needsStackTrace = 0;
int startingPos = 0;
int pos = s.IndexOf("${", startingPos);
while (pos >= 0)
{
if (pos != startingPos)
{
result.Add(new LiteralLayoutRenderer(s.Substring(startingPos, pos - startingPos)));
}
int pos2 = s.IndexOf("}", pos + 2);
if (pos2 >= 0)
{
startingPos = pos2 + 1;
string item = s.Substring(pos + 2, pos2 - pos - 2);
int paramPos = item.IndexOf(':');
string LayoutRenderer = item;
string LayoutRendererParams = null;
if (paramPos >= 0)
{
LayoutRendererParams = LayoutRenderer.Substring(paramPos + 1);
LayoutRenderer = LayoutRenderer.Substring(0, paramPos);
}
LayoutRenderer newLayoutRenderer = LayoutRendererFactory.CreateLayoutRenderer(LayoutRenderer, LayoutRendererParams);
在这个版本中,采取的是简单粗暴的截取字符串的方式。当需要的Render
不存在的时候,创建的是LiteralLayoutRenderer
。当存在的时候,存放在数组里返回。
LiteralLayoutRenderer
本身不做什么格式化输出,只是简单的返回当前模板的值。
protected internal override int GetEstimatedBufferSize(LogEventInfo ev)
{
return _txt.Length;
}
/// <summary>
/// Renders the specified string literal and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
/// <param name="ev">Logging event.</param>
protected internal override void Append(StringBuilder builder, LogEventInfo ev)
{
builder.Append(_txt);
}
最后就是Render的输出了。相比于第一思维的直接string.Replace
,走了一圈Render
的方式更加的安全。
StringBuilder builder = new StringBuilder(size);
for (int i = 0; i < _LayoutRenderers.Length; ++i)
{
LayoutRenderer app = _LayoutRenderers;
try
{
app.Append(builder, ev);
}
catch (Exception ex)
{
if (InternalLogger.IsWarnEnabled)
{
InternalLogger.Warn("Exception in {0}.Append(): {1}.", app.GetType().FullName, ex);
}
}
}
return builder.ToString();
这里有一个比较小的注意点,就是StringBuilder初始化的时候指定一个预估的容量size
,可以较少性能损失。
本文链接:NLog详解(三) - LayoutRender,转载请注明。
没有评论:
发表评论