第 98 题:写出如下代码的打印结果

发布于 2022-06-15 14:14:00 字数 232 浏览 901 评论 42

function changeObjProperty(o) {
  o.siteUrl = "http://www.baidu.com"
  o = new Object()
  o.siteUrl = "http://www.google.com"
} 
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(42

君勿笑 2022-05-04 13:55:40

function(o) 里 o形参是一个LHS查询 相当于 function() { var o = 实参 }
这个题目可以用这样一个角度看
var o = website;
o.siteurl = 'baidu';
o = new Object()
console.log(website.siteurl) // '百度'

得不到的就毁灭 2022-05-04 13:55:40
function changeObjProperty(o) { // 指向内存中的对象,在这里叫做引用o1, o是函数内的一个声明的对象,与下面传进来的webSite的引用相同
  o.siteUrl = "http://www.baidu.com" // 引用在引用o1上加属性
  o = new Object() // 这里是引用o2,与下面webSite的引用不同了
  o.siteUrl = "http://www.google.com" // 引用o2上加属性
} 
let webSite = new Object(); // webSite的引用一直是o1,没改变过
changeObjProperty(webSite);
console.log(webSite.siteUrl); // 所以是baidu.com
那支青花 2022-05-04 13:55:40

请教一下,是因为o.siteUrl是变量声明,所以建立阶段不会被覆盖吗?
那console.log(website.siteUrl);这步的时候前面的代码已经执行了啊?为什么执行阶段也不覆盖呢?

若水般的淡然安静女子 2022-05-04 13:55:40

请教一下,是因为o.siteUrl是变量声明,所以建立阶段不会被覆盖吗?
那console.log(website.siteUrl);这步的时候前面的代码已经执行了啊?为什么执行阶段也不覆盖呢?

我觉得覆盖是对于同一个函数级作用域而言的

无所谓啦 2022-05-04 13:55:40

请教一下,是因为o.siteUrl是变量声明,所以建立阶段不会被覆盖吗?
那console.log(website.siteUrl);这步的时候前面的代码已经执行了啊?为什么执行阶段也不覆盖呢?

抱歉,这里是我看错了题目,我前面看成题目是 var o = new Object(),理解方向错了。实际上本题的关键应该是变量o所指向的内存(对象)发生了变化。

能怎样 2022-05-04 13:55:40

www.baidu.com 形参按值传

随梦而飞# 2022-05-04 13:55:40

function changeObjProperty(o) {
o.siteUrl = "http://www.baidu.com" //给webSite的siteUrl属性赋值
o = new Object() //修改o的引用,此时o与webSite无关了
o.siteUrl = "http://www.google.com" //给新o赋值
}
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl); //http://www.baidu.com

绅刃 2022-05-04 13:55:40
function changeObjProperty(o, str) {
  console.log(copy === o) // true
  o.siteUrl = "http://www.baidu.com"
  o = new Object()
  o.siteUrl = "http://www.google.com"
  str = 456;
} 
let webSite = new Object();
let copy = webSite
let str = '123'
console.log(copy === webSite) // true
changeObjProperty(webSite, str);
console.log(webSite.siteUrl);  // http://www.baidu.com
console.log(str)  // '123'

函数传参,引用类型 copy 对象指向的内存地址,基本类型 copy 值

恋竹姑娘 2022-05-04 13:55:40

一开始真没转过弯来,实践了一下,才明白过来,顺便在这里记录一下:

先让我改造一下:

function changeObjProperty(o) {  
        // o这个形参实际可以写成var o = webSite
       o.siteUrl = "http://www.baidu.com";
       // 偷偷添加一行代码,此时website和o指向同一个堆地址
       // website.siteUrl = "http://www.baidu.com";
     
       o = new Object()  // 相当于 o = {},  o 移情别恋到新的对象引用上去了,而webSite还死心塌地之前的对象引用,因此分道扬镳了
       o.siteUrl = "http://www.google.com"

       return o;
}
let webSite = new Object();  // let webSite = {}
changeObjProperty(webSite);
console.log(webSite.siteUrl);      //  http://www.baidu.com

let newo = changeObjProperty(webSite);
console.log(newo.siteUrl)   // "http://www.google.com"
凹づ凸ル 2022-05-04 13:55:40

因为website是引用类型,o只是对website的引用,改变引用类型的属性可以,但如果o重新赋值相当于重新开辟一块地址,不影响外面的对象(website还是指向原来的地址)

嗳卜坏 2022-05-04 13:55:40

函数的形参与实参修改并非双向~~
正常编程时,不应该修改命名形参;arguments对象中的实参值,都应该作为只读常量来处理
function doAdd(num1, num2) {
arguments[1] = 10
num1 = 50
console.log(arguments[0] + num2)
}
doAdd(10, 20) //60

天荒地未老 2022-05-04 13:55:40
var o = {}


var o1 = o
o.name = "张三"
o1 = {}
o1.name = "李四"

console.log(o.name)

//o1就可以理解为在函数中使用的形参
//传参也是一个变量向另一个变量赋值的过程,当类型为引用类型时,传递的是指针
仅一夜美梦ヽ 2022-05-04 13:55:40

传递参数:
ECMAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个
变量复制到另一个变量一样。基本类型的传递如同基本类型变量的复制一样,而引用类型的值传递,如同引用类型变量的复制一样
可能会困惑:因为访问变量有按值和按引用两种方式,而参数只能按值传递。
会错误的认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的
证明对象是按值传递的:

       ` function setName(obj)
        {
            obj.name='Jack';
            obj=new Object();
            obj.name='Bob';
        }
        var person=new Person();
        setName(person);
        console.log(person.name);       输出Jack`

此例子在《js高级程序设计》一书里面有解释

-梦年海沫深 2022-05-04 13:55:40
// o 是对象webSite的引用
function changeObjProperty(o) {
     // 给webSite的属性siteUrl赋值
     o.siteUrl = "http://www.baidu.com"
     // 创建新对象,新引用并赋值给o,下o非上o
     o = new Object()
     // 给新引用添加属性siteUrl并赋值,和webSite无关
     o.siteUrl = "http://www.google.com"
} 
let webSite = new Object();
// webSite 是个对象,以形参传递,传递的是webSite的引用
changeObjProperty(webSite);
console.log(webSite.siteUrl)
此刻的回忆 2022-05-04 13:55:40

baidu
有些同学可能把[引用类型]和[按引用传递]混淆了 js里函数都是按值传递的

も星光 2022-05-04 13:55:40

函数中的变量o是局部变量,一开始只是和website指向同一个内存,接着局部变量o指向了新的内存(o = new Object()),所以当再次给o添加属性时,由于指向的内存已经和website不一样了,所以website的属性并不会被修改。

人│生佛魔见 2022-05-04 13:55:40

一开始, webSite 和 o 指向的是同一个地址,所以当 o.siteUrl = "http://www.baidu.com" 时, webSite 也共享到了这个 siteUrl : "http://www.baidu.com" 的值。
执行o = new Object(),此时的 o 指向了一个新的地址,webSite 不再和 o 共享数据了,之后 o 再怎么操作都对 webSite 都没有影响了。
所以 webSite.siteUrl = "http://www.baidu.com"

阪姬 2022-05-04 13:55:40
function changeObjProperty(o) {
  //函数参数可以理解为局部变量,传入引用类型执行时,可以理解为:局部变量o与全局变量website同时指向同一个对象
//o现在是引用类型,更改成功,siteUrl = "http://www.baidu.com"
  o.siteUrl = "http://www.baidu.com"
  //更改局部变量o的指向,指向一个新的对象
  o = new Object()
//更改局部变量o指向的新的对象的siteUrl="http://www.google.com"
  o.siteUrl = "http://www.google.com"
//函数执行结束,局部变量o以及指向的新对象释放
} 
//初始化变量
let webSite = new Object();
//进入change调用
changeObjProperty(webSite);

//打印:"http://www.baidu.com"
console.log(webSite.siteUrl);
幸福还没到 2022-05-04 13:55:40
// 这里把o改成a
// webSite引用地址的值copy给a了
function changeObjProperty(a) {
  // 改变对应地址内的对象属性值
  a.siteUrl = "http://www.baidu.com"
  // 变量a指向新的地址 以后的变动和旧地址无关
  a = new Object()
  a.siteUrl = "http://www.google.com"
  a.name = 456
} 
var webSite = new Object();
webSite.name = '123'
changeObjProperty(webSite);
console.log(webSite); // {name: 123, siteUrl: 'http://www.baidu.com'}

非常nice 这个题目和
var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };
console.log(a.x) // undefined
console.log(b.x) // {n:2}
这种类似

好听的两个字的网名 2022-05-04 13:55:40

写出如下代码的打印结果

function changeObjProperty(o) {
  o.siteUrl = "http://www.baidu.com"
  o = new Object()
  o.siteUrl = "http://www.google.com"
} 
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl);
  • webSite该对象的地址传给了变量o
  • 改变o的siteUrl时webSite对应的也改了
  • o = new Object()相当于改变了o的地址,这以后的赋值操作和webSite 都无关了
  • 所以打印webSite.siteUrl就是"http://www.baidu.com"

参考

传递参数:
ECMAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个
变量复制到另一个变量一样。基本类型的传递如同基本类型变量的复制一样,而引用类型的值传递,如同引用类型变量的复制一样

尾戒~ 2022-05-04 13:55:40

http://www.baidu.com
函数的形参是值传递的

感觉这么说不准确。对象传值传的是引用,但是引用是copy给函数形参。

// 这里把o改成a
// webSite引用地址的值copy给a了
function changeObjProperty(a) {
  // 改变对应地址内的对象属性值
  a.siteUrl = "http://www.baidu.com"
  // 变量a指向新的地址 以后的变动和旧地址无关
  a = new Object()
  a.siteUrl = "http://www.google.com"
  a.name = 456
} 
var webSite = new Object();
webSite.name = '123'
changeObjProperty(webSite);
console.log(webSite); // {name: 123, siteUrl: 'http://www.baidu.com'}
// 这里把o改成a
function changeObjProperty(a) {
  /**
   * JS 函数预编译(解析)
   * 
   * 1、执行前的一瞬间,会生成一个AO(action object)对象
   * 2、将函数内的形参和变量声明存储到AO对象中,值为undefined
   * 3、将实参和形参统一,形参作为AO对象的属性名,实参作为AO对象的属性值
   * 
   * ① AO = {}
   * 
   * ① 形成一个局部变量a(形参)
   *   AO = { a: undefined }
   * 
   * ② 把形参与实参结合,即局部变量a与外部变量webSite指向的是同一块堆内存
   *   AO = { a: o的引用地址 }
   */

  // 改变a对象里的值,即改变webSite对象中的值
  a.siteUrl = "http://www.baidu.com"

  // 更改局部变量a的引用,指向新的对象,之后与webSite对象无关
  a = new Object()
  a.siteUrl = "http://www.google.com"
  a.name = 456
} 

var webSite = new Object()
webSite.name = '123'
// 执行函数,把函数放入执行环境栈,进行函数预编译
changeObjProperty(webSite)
console.log(webSite) // {name: 123, siteUrl: 'http://www.baidu.com'}
生活了然无味 2022-05-04 13:55:40

打印的肯定是百度。
至于为什么?
在《JS高程》里,第三版4.1.3里面说到,

ES的所有函数的参数都是按值传递

但是回到这个问题下面,这个参数看起来像是引用传递, 其实传递的不是引用, 而是引用的一个副本。可以称之为共享传递。但是这个引用的副本传递,也可以叫做按值传递, 所以红宝书也没说错。所在在这一句
o.siteUrl = 'http://www.baidu.com'
确实把webSite.siteUrl改成了baidu。但是后续的参数o又指向了新的对象地址。

千寻… 2022-05-04 13:55:40

let a = {}
let b = a
b.name = 'cc'
b = {}
b.name = 'ww'
console.log(a.name) // cc
console.log(b.name) // ww

巷子口的你 2022-05-04 13:55:40

参数 o 是函数内部的变量;
第一次修改 o.siteUrl 时,owebSit 为同一个对象的引用,所以会影响到外面的 webSite 对象;
函数第二行给 o 赋值了一个新对象,此时 owebSite 就是不同对象的引用了;
最后修改 o 时,改变的是新对象的 siteUrl ,而不会影响到外面的 webSite

倾城泪 2022-05-04 13:55:40
// 参数按值传递
// 若传入基本类型值,那么函数参数的值就是传入的值
// 若传入引用类型值,那么函数参数的值是该引用类型值的内存地址
function changeObjProperty(o) {
  // 给传入对象的siteUrl属性赋值为"http://www.baidu.com"
  // 此时webSite对象新增了一个属性siteUrl,值为百度
  o.siteUrl = "http://www.baidu.com"
  // 参数o可以视为一个局部变量,其当前值为webSite对象的内存地址
  // 给o重新复制为空对象的内存地址,从此webSite对象与o无关
  o = new Object()
  o.siteUrl = "http://www.google.com"
} 
let webSite = new Object();
// 将引用类型值webSite传入changeObjProperty函数中
changeObjProperty(webSite);
console.log(webSite.siteUrl); // 百度
浅唱ヾ落雨殇 2022-05-04 13:55:40

ECMAScript 中所有函数的参数都是按值传递的。

潜移默化 2022-05-04 13:55:40
function changeObjProperty(o) {
// 这里的o相当于接收了一个内存地址
  o.siteUrl = "http://www.baidu.com"
// 修改了对于内存地址的参数
  o = new Object()
// 修改了0的内存地址指向
  o.siteUrl = "http://www.google.com"
// 修改新地址的siteUrl
} 
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl);
云裳 2022-05-04 13:55:38

http://www.baidu.com webSite属于复合数据类型,函数参数中以地址传递,修改值会影响到原始值,但如果将其完全替换成另一个值,则原来的值不会受到影响

别闹i 2022-05-04 13:55:34

传进函数的是原对象的地址(或者说引用),这个地址赋值给了形参(形参看做局部变量),形参变量此时指向原对象,后面o=new object的时候,形参变量保存的是新对象的地址,指向的是新的对象,所以第二次的o.siteUrl 也是给这个新对象属性的赋值,和旧对象无关。最后打印website.SiteUrl 的时候,访问的是旧对象,因为前面的改动都只涉及到形参变量,和website无关,website依然保存着旧对象的引用。

坏尐絯 2022-05-04 13:54:44

http://www.baidu.com
函数的形参是值传递的

感觉这么说不准确。对象传值传的是引用,但是引用是copy给函数形参。

// 这里把o改成a
// webSite引用地址的值copy给a了
function changeObjProperty(a) {
  // 改变对应地址内的对象属性值
  a.siteUrl = "http://www.baidu.com"
  // 变量a指向新的地址 以后的变动和旧地址无关
  a = new Object()
  a.siteUrl = "http://www.google.com"
  a.name = 456
} 
var webSite = new Object();
webSite.name = '123'
changeObjProperty(webSite);
console.log(webSite); // {name: 123, siteUrl: 'http://www.baidu.com'}
岁月流歌 2022-05-04 13:51:55

函数的形参是值的传递,传递对象的话,函数接受的是这个对象的指针。

function changeObjProperty(o) {
    o.siteUrl = "http://www.baidu.com"
    o = new Object()//这是一个新的对象
    o.siteUrl = "http://www.google.com"
  } 
  let webSite = new Object();
  changeObjProperty(webSite);

  console.log(webSite.siteUrl);
  //www.baidu.com
不忘初心 2022-05-04 13:45:35

function changeObjProperty(o) {
o.siteUrl = "http://www.baidu.com"
o = new Object() // 形参 o 的指向发生改变,指向堆内存中一个新的对象
o.siteUrl = "http://www.google.com"
}
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl); //"http://www.baidu.com"

所以下面谷歌的赋值是指向新的对象的赋值吗?

鱼忆七猫命九 2022-05-04 12:36:51

function changeObjProperty(o) {
o.siteUrl = "http://www.baidu.com"
o = new Object() // 形参 o 的指向发生改变,指向堆内存中一个新的对象
o.siteUrl = "http://www.google.com"
}
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl); //"http://www.baidu.com"

等数载,海棠开 2022-05-04 07:37:23

I think it’s baidu

尬尬 2022-05-04 02:57:34

http://www.baidu.com
函数的形参是值传递的

~没有更多了~

关于作者

灵芸

每个人心里都住着一个人,或眷念,或暗恋,或想念。

0 文章
0 评论
23713 人气
更多

推荐作者

我们的影子

文章 0 评论 0

素年丶

文章 0 评论 0

南笙

文章 0 评论 0

18215568913

文章 0 评论 0

qq_xk7Ean

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文