JavaScript—之对象参数的引用传递

简介: 变量   1.JavaScript hoisting   >>请看例子,我们拿Chrome的console作为JS的运行环境。 上面直接执行console.log(a), 不带一点悬念地抛出了not defined 错误。

变量

 

1.JavaScript hoisting

 

>>请看例子,我们拿Chrome的console作为JS的运行环境。

上面直接执行console.log(a), 不带一点悬念地抛出了not defined 错误。这是预料之中的。

看下面进化后的代码:

之前变量没有定义的错误没了,取而代之的是告诉我们a的值是 'undefined'。先不管a的值缘何为 'undefined' 了,至少可以知道现a这个变量是定义了,因为之前报的' a is not defined'的错误没有了。

这正是因为JavaScript 中的一个声明提前的特性起的作用。

JavaScript中可以提前使用在后面语句中声明的变量,这种特性叫被国外某网友(ben cherry)称为Hoisting (非官方术语) 。 可以理解为将变量的声明提前了,所以在变量声明前使用变量不会报错。而且这一特性不仅限于变量名,对于函数的声明也是同样的效果。

第一次对函数foo()的调用同样报 'not defined' 错误。这是合情合理同时是合法的。因为从头到尾就没有定义这么一个叫作foo() 的东西。

之后将函数调用写在最前面,但函数的定义我们写在了之后。

 

>> 再来看上面对a的输出值为'undefined'的问题。

这里需要深入理解Hoisting这一特性。它的提前只是将声明提前,而对变量的赋值并没有跟着提前。这点很关键。也就是为什么我们可以在第一句使用变量a但它的值却是 'undefined'。 JavaScript里面声明了但还未赋值的变量其值默认便是 'undefined'。

 

按照Hoisting来解释,最终生成的等价代码其实差不多应该就是这样的:

 

2.直接对字符串字面量调用其方法

 

可以直接对字符串字面量调用方法,JS解析器会自动把字符串变量转为一个字符串类型暂存,然后调用字符串上的方法,完了之后再将暂存的字符串类型销毁。

所以你会看到下面这种用法。

我们可以理解为解析器在后台声明了一个变量暂存这个字符串然后再调用的length方法。

 

函数

 

1.匿名函数无法在声明前调用

 

正如上面介绍的Hoisting特性,函数可以定义在调用之前也可以定义在调用之后:

但仅限于上述这种方式定义的函数。对于匿名函数上述规则不适用。

 

2. 参数变更影响到函数外部

 

当传递给函数的参数是一个数组或对象时,在函数体内对这个传入的参数的更改会影响到函数体外的原传入值。

一般说来,对参数的更改不会影响到原来变量的值,更改只在函数体内起作用:

上述代码中,将name变量赋值为'Wayou Liu' 然后传入change() 函数。在函数体内将传入的参数值改为'Liu Wayou'。然后再输出,不出意外地,输出的是变量原来的值'Wayou Liu'。因为当name传入change函数后,在函数体内,相当于有一个name的副本,这个副本的值等于name,之后在函数体内对其做的操作是在这个副本上进行的。

但情况有所不同,当传入的参数是数组、对象时,在函数体内对参数所做的更改会反映到原变量上。

可以看出,上面代码中已经把friut数组的第一个元素更改了。

下面是关于对象的例子:

可以很明显地看到函数体内对参数的改动影响到了原来的变量,这与通常情况下的传参有质的区别了。需要特别注意。

But,当在函数体内对传入的数组或对象赋值时,这个更改不会反映到函数体外的原变量身上!

请看:

按照上面函数内部的更改会反映到原变量的理论,你肯定觉得执行完change()后person变量的name属性的值已经变成'Tom'了吧。但结果让人有点难以接受。

原因在于,当在函数体内使用赋值操作时,系统就创建了一个变量名为p的变量。这个p是函数内部的变量,对它进行赋值当然只在函数体内起作用,外面的person还是原来的person。

这一步与原来代码的操作差别仅在于在函数体内是对参数赋新值呢还是对参数的属性或数组的元素进行更改。

 

3.使用arguments来接收个数未定的参数

 

有时候我们写了个函数但它接收的参数个数不确定,有时候我们在调用一个函数的时候或许也不确定要传多少个参数。参数需要变成动态的。

这时可以通过函数内arguments来接收传递到一个函数的所有参数。

具体说来,就是在函数体内默认有个arguments变量,它保存了调用这个函数时传递来的所有参数,总个数及每个参数的值。它是一个类似于数组的变量,每个参数会成为它的一个元素,可以通过游标来进行访问。

通过arguments.length可以知道参数个数。

下面这个例子来自MDN:

目录
相关文章
|
1月前
|
JavaScript 前端开发
JavaScript Date(日期) 对象
JavaScript Date(日期) 对象
40 2
|
12天前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
16天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
15天前
|
JavaScript 前端开发
.js方法参数argument
【10月更文挑战第26天】`arguments` 对象为JavaScript函数提供了一种灵活处理参数的方式,能够满足各种不同的参数传递和处理需求,在实际开发中具有广泛的应用价值。
32 7
|
16天前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
1月前
|
存储 JavaScript 前端开发
JavaScript 对象的概念
JavaScript 对象的概念
37 4
|
1月前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
31 1
|
1月前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
16 2
|
1月前
|
JavaScript 前端开发 Unix
Node.js 全局对象
10月更文挑战第5天
26 2
|
1月前
|
存储 JavaScript 前端开发
js中的对象
js中的对象
19 3