js fun(1)(2)

来源:互联网 发布:陈氏太极拳 知乎 编辑:程序博客网 时间:2024/05/14 14:38

原文:http://www.hishenyi.com/archives/796


在群里看到一道其实蛮经典的javascript面试题:题目如下:

 封装一个cout方法,能实现如此调用:cout(a)(b)(c)(d)(e)… 并且返回的值为参数连剩的结果,即a*b*c*d*e*…。如cout(1)(3)(7) 得到21。

这道题乍一看并不难,自己手写起来却是很难,有几个学员都试了一下,毫无结果,难倒了众生。

于是今天我们来解读一下。关键是思路。

思考这个问题需要分几步

一、如果我们封装第一层譬如,

  function xxoo(m)
    {
        return m
    }

   alert(xxoo(3) );

 那么调用后返回的是个数字。 然而数字是无法后面再加一括号执行函数的。难道能 3(4)? 明显不能。

 所以这里有个结论。必须在 xxoo函数中返回一个对象

二、那么问题又来了,如果是对象进行alert 那么我们浏览器弹出来的是一个 Object,并且内容是改对象的源码

大家试一下如下代码

 function xxoo(m)
    {
        return m;
    }

  alert(xxoo) //注意这行

所以这里犯难的是。如果返回计算好的值,那么数字无法继续进行下一层执行。如果返回的是一个对象,那么这个值又不是数字而是一段源码。

所以,这里的结论是,我们要搞清楚js在取值 或者就拿alert(xx) 为列说吧,alert的时候到底发生了什么。

三、为了搞清楚这个过程,我们来看如下代码

  var aa=new String(“hello”) ;//在这里 我们使用了js内置的String对象
  alert(aa);

 弹出的结果 无疑一定是字符串 “hello” 。至于String对象 我们在这不赘述了。大家自行看文档。

 那么接下来我来加一句

 String.prototype.toString=function()   //注意看这里 ,我重写了String对象的内置toString()方法
    {
        return “www.jtthink.com”
    }
     var aa=new String(“hello”)
     alert(aa)

   //这里大家执行后会发现,不管写什么值,都会直接弹出 “www.jtthink.com”,而不是你传入的参数

 toString() 是什么? 官方的解释是:toString() 方法可把一个逻辑值转换为字符串,并返回结果。

 但是很多同学忽略了官方还有这么一段话  :xx对象被用于字符串环境中时,此方法会被自动调用。

四、有了上面第三点的思想我们就能继续想下去了。

  如果我直接alert(String)  弹出什么?

 测试后发现 它弹出的是

  function String() {
    [native code]
}

 这里有一点:当String 对象被实例化后,toString()返回的是该对象函数体或者叫内部计算后最终值,要更改需要使用prototype属性。如果不实例化也就是直接对 元对象 进行toString() . 则返回的是对象的函数体本身,可以理解为底层源码(浏览器引擎源码)

 所以大家继续看代码

  String.toString=function()   //注意看这里 ,我重写了String对象的内置toString()方法
    {
        return “www.jtthink.com”
    }

   alert(String);

这时它就不会弹出native code .而是 “www.jtthink.com“

五、那么我们的思路就很明显了

 按照题目要求,我们只要在函数体内返回一个对象(非实例化的对象),然后重写其toString方法(反正这货会被默认调用哒)

注意,以下代码我是为了让大家能看懂才写的这么繁琐的。其实一个函数可以全部搞定。请大家自行优化

  init=0;  //设置一个全局变量
  var fuck=function(m)
      {
           init=init*m; //如果传值过来,则相乘。当然init如果是0 则一直是0,看下面
          return fuck
      }
      fuck.toString=function()  //这是关键的一步
      {
          return init;
      }
        function xxoo(m)  //最终我们要调用的函数
        {
            init=m ;// 初始化,否则init是0,那么永远乘 都是 0,也是很关键的一步
            return fuck;//最终返回的是 元对象(不是实例化过后的对象哦)
        }
 
    alert(xxoo(3)(4)(5))

注意,以上代码纯为大家能看懂。 正式写不会写这么下流。求懂


0 0
原创粉丝点击