我正在寻找一些关于JavaScript何时通过值传递某些内容、何时通过引用传递、何时修改传递的项影响函数外的值以及何时不影响函数外的值的综合阅读material .我还感兴趣的是,什么时候给另一个变量赋值是通过引用还是通过值,以及这是否遵循了与作为函数参数传递不同的规则.

我做了很多搜索,找到了很多具体的例子(这里有很多这样的例子),我可以从这些例子开始拼凑真正的规则,但我还没有找到一个单独的、写得很好的文档来描述所有这些规则.

另外,语言中有没有方法来控制是通过引用传递还是通过值传递?

以下是一些我想理解的问题.这些只是例子——我实际上是想了解语言所遵循的规则,而不仅仅是具体例子的答案.但是,这里有一些例子:

function f(a,b,c) {
   a = 3;
   b.push("foo");
   c.first = false;
}

var x = 4;
var y = ["eeny", "miny", "mo"];
var z = {first: true};
f(x,y,z);

对于所有不同的类型,x、y和z的内容何时在f范围之外发生变化?

function f() {
    var a = ["1", "2", "3"];
    var b = a[1];
    a[1] = "4";
    // what is the value of b now for all possible data types that the array in "a" might hold?
}

function f() {
    var a = [{yellow: "blue"}, {red: "cyan"}, {green: "magenta"}];
    var b = a[1];
    a[1].red = "tan";
    // what is the value of b now and why?
    b.red = "black";
    // did the value of a[1].red change when I assigned to b.red?
}

如果我想制作一个完全独立的对象副本(没有任何引用),那么最好的做法是什么?

推荐答案

我的理解是,这其实很简单:

  • JavaScript是always按值传递的,但当变量引用对象(包括数组)时,"值"是对对象的引用.
  • 改变变量never的值会改变底层基元或对象,它只是将变量指向新的基元或对象.
  • 但是,更改变量引用的对象的property确实会更改基础对象.

所以,来看看你的一些例子:

function f(a,b,c) {
    // Argument a is re-assigned to a new value.
    // The object or primitive referenced by the original a is unchanged.
    a = 3;
    // Calling b.push changes its properties - it adds
    // a new property b[b.length] with the value "foo".
    // So the object referenced by b has been changed.
    b.push("foo");
    // The "first" property of argument c has been changed.
    // So the object referenced by c has been changed (unless c is a primitive)
    c.first = false;
}

var x = 4;
var y = ["eeny", "miny", "mo"];
var z = {first: true};
f(x,y,z);
console.log(x, y, z.first); // 4, ["eeny", "miny", "mo", "foo"], false

例2:

var a = ["1", "2", {foo:"bar"}];
var b = a[1]; // b is now "2";
var c = a[2]; // c now references {foo:"bar"}
a[1] = "4";   // a is now ["1", "4", {foo:"bar"}]; b still has the value
              // it had at the time of assignment
a[2] = "5";   // a is now ["1", "4", "5"]; c still has the value
              // it had at the time of assignment, i.e. a reference to
              // the object {foo:"bar"}
console.log(b, c.foo); // "2" "bar"

Javascript相关问答推荐

从mat—country—select获取整个Country数组

按下同意按钮与 puppeteer 师

判断表格单元格中是否存在文本框

空的结果抓取网站与Fetch和Cheerio

屏幕右侧屏障上的产卵点""

Prisma具有至少一个值的多对多关系

TypeError:无法分解';React2.useContext(...)';的属性';basename';,因为它为空

为什么客户端没有收到来自服务器的响应消息?

如何在JAVASCRIPT中合并两组对象并返回一些键

以编程方式聚焦的链接将被聚焦,但样式不适用

为什么我的按钮没有从&q;1更改为&q;X&q;?

如何确保预订系统跨不同时区的日期时间处理一致?

为什么当我更新数据库时,我的所有组件都重新呈现?

Phaserjs-创建带有层纹理的精灵层以自定义外观

如果NetSuite中为空,则限制筛选

JavaScript&;Reaction-如何避免在不使用字典/对象的情况下出现地狱?

如果查询为空,则MongoDB将所有文档与$in匹配

带元素数组的Mongo聚合

用内嵌的含selenium的Java脚本抓取网站

TypeScrip Types-向流程对象添加属性