TOM大叔的几道Javascript题目与解答

时间:2022-08-26 17:57:06

几道JS题目

之前没有深入研究js语言,最近几年前端越来越工程化,需要扎实的js基础,看到博客园上有很多大牛分享JS学习文章,幸运看到tom大叔的blog,抽时间潜心学习了其文章,遇到到其出的几道题目,尝试自己解决,以测试自己的js水平。

http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html

  1. 找出数字数组中最大的元素(使用Match.max函数)
  2. 转化一个数字数组为function数组(每个function都弹出相应的数字)
  3. 给object数组进行排序(排序条件是每个元素对象的属性个数)
  4. 利用JavaScript打印出Fibonacci数(不使用全局变量)
  5. 实现如下语法的功能:var a = (5).plus(3).minus(6); //2
  6. 实现如下语法的功能:var a = add(2)(3)(4); //9

找出数字数组中最大的元素(使用Match.max函数)

问题棘手点在 Math.max的入参是离散的, 即时,函数的参数一一列举, 逗号隔开, 形式如 Math.max(a,b,c)。

但是只凭js,没有任何一种方法,将数组离散化后,再传给Math.max方法, 如果数组为 后台变量还可以使用后台离散方法,写法为 Math.max(<%=arr.join(“,”)%>)。

对于函数和参数的考虑,我们往往能够想到, 一个使得参数变换调用方式的方法, func.apply(obj, argArr) == func.call(obj, arg1, arg2,…)

即 apply 调用能够使得参数组织为数组形式, 但是调用后, 其效果等价于 参数列举形式。

但是其第一个参数为函数中this指代的对象, 如果一个函数其中没有this使用, 则可以使用apply方式, 满足函数定义为参数列举, 但是实际参数为数组的情况。实现代码:

var numArr = [

1,
  2,
  44
];
console.log(Math.max.apply(null, numArr))

注意 其中apply第一个参数为 null 或者 undefined, 表示如果max函数中有this应用,则this指代宿主对象, window。

执行结果:

TOM大叔的几道Javascript题目与解答

进一步延伸

如果有一个函数,只有一个参数, 要求为数组, 但是应用中需要按照参数列举(每个参数为数组元素)方式使用此函数,则如何是好?

看如下方法:

1、 test函数接受一个入参, 要求是数组,此函数将打印数组中每个元素。

2、 我们首先想到, call可以将列举参数 收集到 函数的 arguments 对象中, 但是如果使用 test.call(null, 1, 3), 则需要test函数针对arguments做直接取值操作(arguments[index])), 与其内部已经实现的代码逻辑不一致:

function test(){
  for(var index in arguments){
     console.log(arguments[index])
  }
}

实际上arguments是一个对象, 而且是 Array-like类型的, 这是什么玩意?请见 http://tunps.com/javascript-array-like-object

这种类型,可以使用 Array.prototype.slice 函数将其转换为真正的数组。转换为数组后,就满足test函数参数定义规则了。 完整代码如下:

// test 入参为一个数组
function test(){
  for(var index in arguments[0]){
     console.log(arguments[0][index])
  }
}
test([1, 3]);

//test.call(null, 1, 3);  // need test use arguments[index] to get value

// 将 1, 3, 3 转换为素组调用
function testCall(){
   test(Array.prototype.slice.call(arguments))
}

testCall(1, 3);

执行结果:

TOM大叔的几道Javascript题目与解答

转化一个数字数组为function数组(每个function都弹出相应的数字)

主要考察闭包用法(闭包可以构造一个保留执行现场状态的小环境,并且每次访问闭包函数,都能够访问和设置此小环境)。

比较基础,直接上代码:

var numArr = [
  1,
  2,
  44
];

for (i in numArr)
{
  numArr[i] = (function(num){
    return function()
    {
      console.log(num)
    }
  })(numArr[i]);
}

for (i in numArr)
{
  numArr[i]();
}

执行结果:

TOM大叔的几道Javascript题目与解答

给object数组进行排序(排序条件是每个元素对象的属性个数)

通过属性访问区分(hasOwnProperty),考虑对原型概念的理解, 并且对数组为引用类型的理解。

代码:

var numArr = [
  {"a":"b"},
  {"a":"b", "oo":"pp", "uu":"qq"},
  {"a":"b", "ll":"b"}
];

console.log("numArr is Array="+(numArr instanceof Array))

var i = 0
var tmp = numArr[i];
console.log("tmp="+tmp)

//获取对象自身属性个数
function GetPropertyNum(obj){
  var num = 0;
  for (var key in obj){
    if ( obj.hasOwnProperty(key) )
    {
        num ++;
    }
  }
  return num;
}

// test GetPropertyNum
console.log(GetPropertyNum({"a":"b"}))

//使用冒泡排序
function BubbleSort(arr, cmpFunc)
{
  for( var i=0; i<=arr.length-2; i++ )
  {
    for ( var j=0; j<=arr.length-2-i; j++ )
    {
      //前一个大于后一个
      var pre = arr[j];
      var next = arr[j+1];
      if ( cmpFunc(pre,next) > 0 )
      {
         var tmpObj = arr[j];
         arr[j] = arr[j+1];
         arr[j+1] = tmpObj;
      }
    }
  }
}

// 对象属性数目大小比较函数
function ObjectPropertyCmp(obj1, obj2)
{
  var preCount = GetPropertyNum(obj1);
  var nextCount = GetPropertyNum(obj2);
  if ( preCount > nextCount )
  {
    return 1;
  }
  else if ( preCount === nextCount )
  {
    return 0;
  }
  else
  {
    return -1
  }
}

console.log("----- before buble sort -----------")
for (var i in numArr){
  console.log(numArr[i]);
}

BubbleSort(numArr, ObjectPropertyCmp);

console.log("----- after buble sort -----------")
for (var i in numArr){
  console.log(numArr[i]);
}

执行结果:

TOM大叔的几道Javascript题目与解答

利用JavaScript打印出Fibonacci数(不使用全局变量)

考察闭包实现执行过程状态保存的功能。

代码:

// 创建fibonaci生成器, 生成闭包, 存储 prev 和 current环境

function createFibonaci()
{
  var prev = 0;
  var current = 1;
  return function(){
    var result = prev + current;
    prev = current;
    current = result;
    return current;
  }
}

//按照下标打印fibonaci数列
function printFibonaci(order)
{
  var fiboArr = [0, 1];
  var fibonaciGenerator = createFibonaci();
  for( var i=2; i<=order; i++ )
  {
    fiboArr.push(fibonaciGenerator());
  }
  for ( var i in fiboArr )
  {
    console.log("fibo index="+i+"; fibonum="+fiboArr[i]);
  }
}

printFibonaci(8);

执行结果:

TOM大叔的几道Javascript题目与解答

实现如下语法的功能:var a = (5).plus(3).minus(6); //2

考察基本数据类型, 以及和对应对象的关系, 并在原型中添加新方法的让特定对象支持新特性。

(5). xxx 将会把5转换为 对象, 相当于 (new Number(5)).xxx

xxx (plus) 是不存在的, 则需要在 Number原型中添加plus方法, Number.prototype.plus = ??

plus方法调用后,还可以调用minus方法, 则plus函数返回一个 数值基本数据类型的变量, 同时minus也需要在Number原型中添加。

上代码,请细品:

// Number类型值转换为 Number对象
var numObj = new Number(5);
console.log("numObj type="+typeof numObj);

// Number对象获取 Number类型值
var num = numObj.valueOf();
console.log("num = "+num);
console.log("num type="+typeof num);

Number.prototype.plus = function(num){
  var thisNum = this.valueOf();
  return thisNum + num;
}

Number.prototype.minus = function(num){
  var thisNum = this.valueOf();
  return thisNum - num;
}

var a = (5).plus(3).minus(6);
console.log("a="+a);

执行结果:

TOM大叔的几道Javascript题目与解答

实现如下语法的功能:var a = add(2)(3)(4); //9

考察 闭包 + 原型链(函数重载)+对象取值函数valueOf等概念。

首先,  add是一个函数, 观察其后有 2 3 4, 结果又为9 , 大概意思为分三次相加, 值能够保存在某个地方。

其次, add(2) 后面 有  (3), 则表示 add(2) 返回的 也是一个函数, 记为 func, 则add(2)(3) == func(3), 此func也有add的功能,是将3加到add(2)保存的变量中,则让人联想到 add是闭包产生。

最后, xxx(4)之后, 其 被赋值给 变量 a, 从前面分析知道 xxx(4)应该返回也是一个函数, 这个函数具有add的功能, 则函数如何取得其值呢? 有请对象的valueOf方法出场。(这个add明明是函数, 对什么说其是对象,并拥有对象的valueOf方法呢? 请看 http://www.cnblogs.com/wangfupeng1988/p/3979533.html

上代码:

function createAddFunc()
{
  var sum = 0;

function add(num){
    sum += num;
   
    return add;
  };

add.valueOf = function(){
      return sum; 
  };
   
  return add;
}

var add = createAddFunc();

var a = add(2)(3)(4);

console.log("a="+a);//a = 9

执行结果:

TOM大叔的几道Javascript题目与解答

完结,真正研究过,确实学到不少东西。感谢大叔出题。

博客园上有其他同学,做过,附上做参考吧,(不论好坏,每天daydayup即可,欢迎指正):

http://www.cnblogs.com/yanyd/p/4202583.html

TOM大叔的几道Javascript题目与解答的更多相关文章

  1. 汤姆大叔的6道js题目

    汤姆大叔的6道javascript编程题题解 看汤姆大叔的博文,其中有篇(猛戳这里)的最后有6道编程题,于是我也试试,大家都可以先试试. 1.找出数字数组中最大的元素(使用Math.max函数) 1 ...

  2. 汤姆大叔的6道javascript编程题题解

    看汤姆大叔的博文,其中有篇(猛戳这里)的最后有6道编程题,于是我也试试,大家都可以先试试. 1.找出数字数组中最大的元素(使用Math.max函数) var a = [1, 2, 3, 6, 5, 4 ...

  3. 你应该知道的25道Javascript面试题

    题目来自 25 Essential JavaScript Interview Questions.闲来无事,正好切一下. 一 What is a potential pitfall with usin ...

  4. 解Tom大叔出的Javascript题目

    原文参考,http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html Tom大叔的博客深入理解Javascript系列真是我们学习Java ...

  5. 汤姆大叔 javascript 系列 第20课 最后的5到javascript题目

    博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 原题: 大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4 ...

  6. javascript - 浏览TOM大叔博客的学习笔记

    part1 ---------------------------------------------------------------------------------------------- ...

  7. 【19道XSS题目】不服来战!&lpar;转&rpar;

    [19道XSS题目]不服来战! 记得第一次接触xss这个概念是在高中,那个时候和一个好基友通过黑客X档案和黑客手册.第一次接触到了除了游戏以外的电脑知识,然后知道了,原来电脑除了玩游戏还可以搞这些,从 ...

  8. 44道JavaScript送命题

    很久以前看过一个老外写的帖子,JavaScript Puzzlers!,直译就是JavaScript难题,里面列举了100道JavaScript选择题,大部分都是让人摸不着头脑的题目,需要仔细琢磨一番 ...

  9. 试试看 ? 离奇古怪的javascript题目

    来源地址: http://dmitrysoshnikov.com/ecmascript/the-quiz/#q1 另一篇帖子 看看国外的javascript题目,你能全部做对吗? http://www ...

随机推荐

  1. for循环或Repeat里面对某个字段进行复杂处理的解决方案

    在后台用一个方法处理

  2. Javascript nextElementSibling和nextSibling

    function next(ele) { if (typeof ele.nextElementSibling == 'object') { return ele.nextElementSibling; ...

  3. jquery&period;loadmask&period;js

    Quick Start 下载之后的目录结构如下图所示: 使用此插件非常简单,如下步骤所示: 1.  引用jquery,1.2.3以上版本 <script type="text/java ...

  4. CSS 初体验之Line-height

    p{ line-height:20px; } line-height : normal | length 参数: normal : 默认行高length : 百分比数字 | 由浮点数字和单位标识符组成 ...

  5. Div&plus;Css的初步运用

    采用DIV+CSS模式的网站具有以下优势:1.表现和内容相分离 2.代码简洁,提高页面浏览速度 3.易于维护和改版 4.提高搜索引擎对网页的索引效率. 然后呢html文件中放置CSS有三种类型:内联. ...

  6. java中常用的数据加密算法

    以下为加密的工具类: import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; im ...

  7. Zepto源码分析-event模块

    源码注释 // Zepto.js // (c) 2010-2015 Thomas Fuchs // Zepto.js may be freely distributed under the MIT l ...

  8. selenium环境配置

    在命令提示符中查找 pip的位置 where pip 输入pip,出现一下信息显示,如果提示['pip' 不是内部或外部命令,也不是可运行的程序 或批处理文件.]请查看你的系统Path 上查看你的配置 ...

  9. Linux输入子系统 &colon; 按键驱动

    一.Linux input system框架: 1.由输入子系统核心层(input.c),驱动层(gpio_keys.c)和事件处理层(Event Handler)三部份组: 2.主要的三个结构体:i ...

  10. 删除list中的特定元素

    对于动态删除list中的特定元素,一般用linkedList,删除时有以下两种方法. 1. 循环遍历,找到要删除的元素后删除并且减少list长度.如果不减少list长度,那么就仅仅删除了元素,但没改变 ...