江太公:javascript count(a)(b)(c)(d)运行过程思考

昨天,我弟抛给我一个js的题,使用类似标题那样的调用方法计算a*b*c*d以致无穷的实现方法。思考了半天,终于理清了它的运行过程,记录于下:

函数体:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>a</title>
 5 </head>
 6 <body>
 7 <p id="a"></p>
 8 <script type="text/javascript">
 9 function count(x){
10      var fn = function(y){
11           return count(x*y);
12      }
13      fn.toString = function(){
14           return x;
15      };
16      return fn;
17 }
18 alert(count(77)(33)(55));
19 </script>
20 </body>
21 </html>

这个函数的另外一个实现方法:

<!DOCTYPE html>
<html>
<head>
    <title>a</title>
</head>
<body>
<p id="a"></p>
<script type="text/javascript">
function count(x){
     count.toString = function(){
          return this.p;
     };
     count.p = (count.p || 1)* x;
     return count;
}
alert(count(77)(33)(55));
</script>
</body>
</html>

第一种:

如果计算一个单值,count(77),fn被赋值一个函数function(){return count(x*y)},这个函数的目的是传另外参数并返回函数本体进行递归,当然此时只是赋值不会调用,接着将fn的内置构造函数重新定义为function(){return x;},其目的是当fn被调用的时候,自动调用toString方法,返回传过来的x值,最后返回被赋值函数的fn变量。此时fn的toString方法被调起,返回77。结束。

而若计算count(77)(33),第一次运行过程跟上面类似,当fn被调起的时候实际类同于fn(33),也即33作为y参传入被赋值函数的fn变量函数,由于未退出count函数体,x参未被覆盖,还被驻留在内存中,因此在count(x*y)中被计算,成了count(77*33)也即count(2541),这个计算过程发生在fn被调用的时候,然后递归调用count,此时x变为2541,fn的toString的x将返回这个值。也即在结束跳出函数体的时候fn调用了toString最终返回2541。

再计算count(77)(33)(55),前面运算过程同上,此时被传入的x是2541,fn被赋值函数体,fn的toString方法被重写,然后fn返回,如果被调起,则进入fn的函数体执行,此时的x2541还在内存中,y55被传入,count再次递归,x变成了2541*55,即139755,被作为toString自动调起的时候的返回值返回。

第二种:

给函数定义一个变量p,p的初始值被赋予了1,目的是在做第一次乘法运算的时候不改变x值,将其与传进来的x参数进行乘积后的结果返回给toString这个自调起的方法,当count在最后返回的时候,自动调用toString,计算count(33)(55)(77),它就是一步步从里到外计算的过程,每次都改变传入的this.p值,最终返回他。

以上即是对这个问题实现后js内部运行过程的思考。不知对还是不对。有大神经过麻烦指教。

时间: 2024-07-31 16:23:41

江太公:javascript count(a)(b)(c)(d)运行过程思考的相关文章

[JavaScript] js实现简单的代码运行框

<script type="text/javascript">// <![CDATA[ function runCode(obj) { var winname = window.open('', "_blank", ''); winname.document.open('text/html', 'replace'); winname.document.write(obj.value); winname.document.close(); } //

[LeetCode][JavaScript]Count of Smaller Numbers After Self

Count of Smaller Numbers After Self You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. Example: Given nums = [5,

[LeetCode][JavaScript]Count Primes

Count Prime Description: Count the number of prime numbers less than a non-negative number, n. https://leetcode.com/problems/count-primes/ 找出所有小于n的数中的质数. 删数法.开一个1到n的数组,删除所有2的倍数,3的倍数...直到√n的倍数,最后剩下的就是质数. 1 /** 2 * @param {number} n 3 * @return {number

[LeetCode][JavaScript]Count Complete Tree Nodes

Count Complete Tree Nodes Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from Wikipedia:In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last le

【Hight Performance Javascript】——脚本加载和运行

脚本加载和运行 当浏览器遇到一个<script>标签时,无法预知javascript是否在<p>标签中添加内容.因此,浏览器停下来,运行javascript代码,然后继续解析.翻译页面. 浏览器必须首先下载外部文件的代码,这要占用一些时间,然后解析并运行代码,这又要占用一些时间.此过程中,页面解析和用户交互是被完全阻塞的. 将脚本放在底部 合并脚本减少个数 延迟脚本(defer) <script src="file1.js" defer></s

javascript运行过程中的“预编译阶段”和“执行阶段”

javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段 而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块为范围<script></script>,即每遇到一个代码块都会进行  预编译>执行), 首先科普下javascript中的两种声明方式,var和function,前者声明的是变量,后者声明的是方法 在预编译中,javascript对这两种声明做出了两种处理方案 <scri

理解JavaScript的执行机制

一直没有深入了解过JavaScript的事件执行机制,直到看到了这篇文章:<这一次,彻底弄懂JavaScript执行机制> 才发觉熟悉JavaScript的执行机制非常重要. 毕竟在跟进项目中偶尔需要排查为什么会出现函数执行顺序不一样的情况. 感谢作者浅显易懂的文字让我获益匪浅,以下是自己对JavaScript执行机制的理解,全是流水账. 文章主要叙述: 1:单线程和异步任务 2: 异步任务的分类 3:setTimeout 和 setInterval 的执行方式 单线程和异步任务 JavaSc

跨域的一些方法

一.什么是跨域理解跨域首先要理解同源策略,它是浏览器对js施加的一种安全限制.所谓同源是指协议.域名.端口必须相同.浏览器在请求数据时都要遵循同源策略,那么凡是发送请求的URL中协议.域名.端口三者之中的一点不同时,就叫做跨域. 二.jsonp 1.什么是jsonp JSONP(JSON with Padding)是资料格式 JSON 的一种"使用模式",是被包含在函数调用中的JSON.它由两部分组成:回调函数和数据. 2.jsonp跨域的原理 直接用XMLHttpRequest请求不

(转)Eclipse中查看jar包中的源码

Java Decompiler Plugin For Eclipse IDE 1. 下载JAD ,  1.5.8版本的jad在 http://www.softpedia.com/progDownload/JAD-Download-85911.html 将展开后的jad.exe放到某个目录,例如 c:/jad/jad.exe 2. 下载JADClipse插件 http://sourceforge.net/projects/jadclipse/files/ 将展开后的net.sf.jadclipse