问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

js函数中什么是形参,什么是实参,两者有什么区别?

发布网友 发布时间:2022-05-14 17:38

我来回答

3个回答

懂视网 时间:2022-05-14 21:59

如何定义作用域链

作用域链为一个对象的列表,每次调用js函数的时候,都会创建一个新的对象来保存其局部变量,把这个对象添加到作用域链中,如果函数返回,就从作用域链中将绑定的对象删除,如果不存在嵌套函数,也不存在其引用指向这个绑定的对象,会被js解释器的垃圾回收机制不定时的回收,是不定时的,不是在没有完全引用的时候立马删除,如果定义了嵌套函数,每个嵌套函数都各自对应着一个作用域链,并且这个作用域链指向一个变量绑定的对象。如果这些嵌套函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样当做垃圾进行回收,如果这个函数定义了嵌套的函数,并将它作为返回值返回,或者存储在某处属性里,会有外部引用指向这个嵌套函数,即不会被当做垃圾回收,其变量所绑定的对象也不会当做垃圾进行回收。

函数执行完毕以后相关的作用域链不会删除,只有当不在有引用的时候,才会进行删除操作

884710466-5b4b6f3028f51_articlex[1].png

关于栈的说明

原始栈
栈顶 window
执行下列js脚本

function a() {
 function f() {
 return 333;
 }
 return f;
}
a()();

栈顶 a → window
开始调用,执行到return
发现需要调用f
继续加栈
栈顶 f → a → window
执行完f弹出f
继续执行a,执行完毕弹出a
最后全部执行完毕弹出window

算了文字解释太无力,直接上代码

var scope = "global scope"; // 一个全局变量
function checkscope() 
{
 
 var scope = "local scope"; // 定义一个局部变量
 
 function f() 
 {
 return scope; // 返回变量作用域中的scope的值
 }
 
 return f(); // 返回这个函数
}

调用一下这个函数

checkscope();
"local scope"

接着这样执行

var scope = "global scope"; // 一个全局变量
function checkscope() 
{
 
 var scope = "local scope"; // 定义一个局部变量
 
 function f() 
 {
 return scope; // 返回变量作用域中的scope的值
 }
 
 return f; // 返回这个函数
}

继续调用函数

checkscope()();
"local scope"

闭包有什么用

先看一个函数uniqueInteger()使用这个函数能够跟踪上次的返回值

var uniqueInteger = (
 function() {
 var count = 0;
 return function() {return count++}
 }()
);

这样子就使用闭包

uniqueInteger();
0
uniqueInteger();
1

每次返回是其上一次的值,并随便直接将值加1
至于为什么要这样写,如果不使用闭包,那么恶意代码就可以随便的将计数器重置了。。

uniqueInteger.count = 0;
function uniqueInteger() {
 return uniqueInteger.count++;
}

类似这样的,完全可以做到直接通过赋值,将其count的值重置。
而如果使用闭包,没有办法进行修改,为私有状态,也不会导致其一个页面内变量的冲突,或者是其覆盖。

立即调用的函数

var a = (function c(){
 var a = 1;
 a++;
 console.log('已经执行');
 return function b(){return a++};
}())

额,我大概解释一下这段代码。
首先呢,解释最外层的圆括号,因为如果没有圆括号,则这个是一个赋值语句,将一个匿名函数赋值给变量a,实际上是在内存中完成了栈中变量a指向匿名函数存储的空间的地址,如果有圆括号,实际上是告诉js解释器这是一个语句,需要js执行,消除了其function带来的影响。(ps;貌似火狐上不加也可以,也可以正常的运行)执行和引用的关系下方有。
然后呢,最后的圆括号,代表着其执行这个函数,因为js解析器将()解析为调用前方的函数名称,类似于运算符吧。但是实际上并不是运算符,因为能往其内传值,注意,这点是将其执行的结果保存在堆中,并完成其指向
其后,当直接输入a;,实际上执行并完成了一次调用,其返回值为函数b,将函数b完成一次引用,即变量a引用函数b,由于其存在引用关系,即栈中变量a保存的为其函数a的返回结果,(因为其不是不是对象,如果写a()()表示将函数a调用后返回的对象保存在栈中,然后将栈中的内容再次调用,由于是保存,并不存在其应用关系,所以执行完毕后直接垃圾回收)由于其保存的是函数b的作用域链,而函数b的作用域链是继承自函数a的作用域链,但是由于函数a的作用域链并没有引用导致其执行完后被垃圾回收(当不在有变量指向的时候)。所以呢,函数其值是在函数b中进行保存,如果修改函数c此时函数c并不会影响到函数b中的保存,因为其函数c的变量列表已被销毁,
最后,继续讨论起嵌套函数的引用,由于其父函数已被销毁,但是嵌套函数被引用,(注意:因为其父已经没有,所以是另开辟一块新的堆空间,用于存储其函数c的返回结果,注意是返回结果,而不是函数b)此时另外指定变量保存其结果,无论指定多少个变量保存其结果,都是新的空间的执行,没有任何的干扰,详细了解看下面,继续讨论

  1. ps;如果是()()则代表其会被其垃圾回收

  2. ps 还需要注意一点点的是由于其引用的是result的值,并不是其

最后,这样就能完成其变量保存在函数中,貌似叫做记忆?

所以呢,借助堆和栈就很好的能理解了闭包

再继续看代码

function count() {
 var n = 0;
 return {
 count: function() { return n++; },
 reset: function() { n = 0; }
 };
}
var c = count(); var d = count();
undefined

在分别执行一下下

c.count();
0
d.count();
0
c.count();
1
d.count();
1
c.reset();
undefined
c.count();
0
d.count();
2

这一点体现了其互不影响性,表明其由于其父被回收,导致其子分别开创了一块在堆中新的内存空间,并完成其指向,互相不干扰。
其作用域链互不干扰

使用getter和setter完成其闭包

function count(n) {
 return {
 get count() { return n++; },
 set count(m) { 
 if ( m >= n)
 n = m;
 else
 throw new Error( '请输入一个正确的值' );
 },
 };
}

这个就不用解释啦,很简单啦

同一个作用域链中定义两个闭包

function test1() {
 val = value = 111;
 this.test = function() { return value - 1; };
 this.test2 = function() { return value + 1; };
 
}

这同样是两个作用链域
不过这样写需要先执行其o.test1(),因为其方法在其函数内部,必须先执行一下,完成其方法的添加,否则会报错,

ee.test is not a function

提示找不到这个方法,
因为执行

ee.test1 = test1;
function test1()

只是简单的进行赋值,并不能进行查看,所以导致其无法使用
所以嘛,要先执行一遍,让其方法添加进去

ee.test1();
undefined
ee.test();
110
ee.test2();
112

这就是两个闭包,这两个闭包互相平行,同时继承于其父,但是又不受其父影响,很神奇吧,(@ο@)

叮 又发现一个莫名奇妙的东东 https://us.leancloud.cn 貌似目前水平能看懂一些了

关于this的问题

this在父闭包显示的即为使用该方法的对象。
但是子就不一定了。

function test1() {
 val = value = 111;
 this.test = function() { return this.x - 1; };
 this.test2 = function() { return this.x + 1; };
}

执行一下

ee.test();
4443

这就尴尬了。
好吧。只能说是一般不这样用
一般这样写

var self = this;

将其值保存进一个self中

热心网友 时间:2022-05-14 19:07

5个,这里没有什么疑问的!
从形式上看很看是两个的,因为有二个为一组做为一个对象,有三个为一组做为一个对象,共有两个.所以应该说是两个,而从我的感觉当中这样是不对的,因为在JS中不存在(exp1,exp2)这样的定义方法,他不是{1,2}而是(1,2),而且()的做用除了VB中的索引外,在JS中只是改变了运算符的优先顺序,而这里改变的显然是,运算符的优选顺序,而,运算本身的优选顺序是自左向右,所以这里除了改变顺序达到一个特殊目的,但如果不考虑这个特殊目的,那么,加了括号跟不加是没有区别的.所以这里的参数是五个而不是两个!
当然你完全可以做一个验证:定义一个有五个形参的函数,然后加括号传值,看一下是否成功!

热心网友 时间:2022-05-14 20:25

参数又称参变量,在js中函数接收的变量分为形参和实参。实参是指实际参与js函数调用使用的具体数据。形参是指函数被调用时,接收实参值的变量。根据实际需要,形参可有可无,没有形参时,圆括号也不可省略。当出现多个参数时,参数之间用英文逗号,隔开。

实例:

window.onload=function()

{

function compare(a,b)

{

return(a>b?a:b)

}

alert(compare(5,9));

}

在函数compare()中,a,b为形参,alert函数在调用compare()中输入的5,9为实参。

我的个人博客会不定期写一些基础的前端知识,有兴趣的朋友可以去踩一下:弹幕猴子

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
脚崴了挂什么科、急急急 linux 解压缩工具--tar命令 生日祝福语闺蜜 简短独特暖心 QQ有哪些隐藏的图标??他们分别是什么??怎么样点亮?? QQ业务的各种图标怎么点亮? qq怎么点亮图标和名字 诗中书万象=求下联 大爱如山藏万象下联 中国电子展:电位器和可调电阻的区别是什么?这四点很明显 电位器的接线方法是什么 电位器的工作原理如何 k508遵义到南阳火车票为什么买不了 哈尔滨那里的住宅比较适合居住,最好要小区式的环境比较好的。价格比较合理的,稍微远点无所谓。 保定火车站电话是多少 四环内有什么新房项目? 18号上海到达州火车停运了吗? 四环内或刚出四环的1000万左右新房项目 鼓膜穿孔的治疗方法有哪些? 2020年2月3号k508停运了吗? D850照片拍摄菜单里NEFi记录此选项不可用? 尼康d850菜单设定如何取消小星星? Nikon D850相机菜单如何将英语改为汉语 尼康d850怎样设置快捷键水平仪? 尼康d850相机将多重曝光自动关闭了怎么设置才能打开 尼康d850如何设置版权 华为AI音箱,如何连接台式电脑?(我的电脑有USB蓝牙适配器)在线等高人回答!! 澳柯玛标准电动车车架号在哪里? 学习图片PS难吗? 春秋打仗礼仪谁破坏的 春秋打仗的规矩 历史上第一幅春联对仗 14年上海铁路7月1日铁路调整具体路线 请问动车票和谐号达洲到北京的3个问题,谢谢了! 重庆到北京西站火车停多少站k508 襄阳东站到北京西站k262停运了吗 怎么清洗过氧化钠留在地砖上的痕迹? 贵阳到邓州火车k474 瓷砖上的电焊痕迹怎么去除? 埃及消消乐阵容搭配 厚街莞太路101号能办到工商营业执照吗 路政和运政是一回事吗,是一个单位不?哪个职权大,权利大? 快乐大本营推荐的消消乐 求推荐类似于开心消消乐的游戏,记得有个什么宝石的也挺好玩的。 开心消消乐中推荐好友这个选项怎么没有了? 我的好友/推荐好友/添加好友 农村房屋确权证是什么样的 房产确权要什么 你们玩开心消消乐吗? 很多年轻人一半工资交房租,为什么房租费这么高? 如果政府认为市场上的房租太高,它应该从哪些政策来控制租金? 房租涨幅太高找哪个部门投诉 房子我买不起租的房子租金越来越高我该怎么办呢?