-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【10.3练习】 #643
Comments
实践是检验真理的唯一标准
我初步的分析是 结果应该是 1 和 2
原因何在** 首先我们要明确一点:JavaScript中所有函数的参数都是按值来传递的 **
console.log(number); 上述的打印结果是 2 1 同样都是传值,和之前给出的例子, 得到的结果 是不一样的。
这里涉及到JavaScript的数据类型 JavaScript数据类型
原始值类型 变量存储的就是具体的值 回光返照output(obj); 传入了一个变量 obj, 函数传递参数 都是按值传递 如何才能不影响外面的对象答案就是: 不能操作同一个对象 而要操作不同的对象。
幸运的时 ES6 有个 assign 方法 就是做这个事的
|
把代码扔进chrome浏览器,返回结果
两次的返回结果是一样的。下面我们来一行行解释代码运行 定义obj 对象
output 函数声明
调用函数output。
发生了什么? 题外话《Javascript 面向对象精要》指出,JS的数据类型可大致分为两种:原始类型和引用类型。 ——《javascript 面向对象精要》1.3 |
自己在运行代码之前心里想的结果是:false和1(因为1不等于2,所以应该就是false吧)。运行结果出现2和2的时候,发现根本没有在用计算机语言思考问题。 obj这个对象中count的值是1,属性是number,而number是原始值,是不可更改的。 根据犀牛书page46:“存取数字时创建的临时对象称作包装对象,它只是偶尔用来区分数字和数值对象。"(通常,包装对象只是被看作是一种实现细节,而不用特别关注) 把console.log(obj.count)这一行的位置调整一下,输出结果变为:1和2
所以,原来的函数output(obj)中:obj.count = obj.count + 1;可以理解为是在原始值1的基础上增加1,经过这一行代码的计算之后,新的临时值变成2,所以output(obj)的输出结果为2. 在此基础上运行console.log(obj.count)输出的应该还是包装对象的值,所以还是2. 我能够想到的办法让函数内的计算不影响函数外的obj.count办法是:
|
在执行 函数 output(obj) 中,语句直接对obj对象的属性进行了操作,改变了内存里obj对象的属性值。 var obj = { function output(obj) { |
var obj = {
count: 1
}
function output(obj) {
obj.count = obj.count + 1;
console.log(obj.count);
} 在上面代码之后,执行下面代码分别输出什么? output(obj);
console.log(obj.count); 初步分析与实践未运行之前,判断输出是:2,1; 于是我重新录入变量和函数,这次把最后的两行代码调换一下: console.log(obj.count);
output(obj); 得到的结果是:1,2。 原因分析:
var obj = {
count: 1
}
function output(obj) {
var count = obj.count
count = count + 1;
console.log(count);
}
output(obj);
console.log(obj.count); |
执行的结果是一样的,因为在使用对象作为函数参数时,实际上传送给函数的是对象的地址,即函数体内的对象和作为参数的原对象实际上是同一个。所以,想要不影响外面的obj,就需要在函数体内定义一个局部的obj对象,并复制外部obj的值。 var obj = {
count: 1
}
function output(obj) {
var obj = JSON.parse(JSON.stringify(obj));
obj.count = obj.count + 1;
console.log(obj.count);
} |
@freedomsky11 的答案正解! 先看一种情况。 var obj = {
count: 1
}
var anotherObj = {
count: 1
}
console.log(anotherObj === obj);
=> false 分别定义了obj和anotherOjb,他们的对象实体内容虽然都一样,但还是不同的对象。 对象赋值并不是等于复制对象,而是引用。 var obj = {
count: 1
}
var anotherObj = obj; 此时anotherObj和obj是指向同一个对象实体。anotherObj此时是obj的引用,引用就像别名一样。 比如王宝强这个人还有一个小名叫“傻根”。不管是王宝强还是傻根,都是指向同一个人。 console.log(anotherObj === obj);
=> true 通过以上判断,可以认为两者是同一个对象。 function output(obj) {
obj.count = obj.count + 1;
console.log(obj.count);
} 基于以上分析,output函数的形参对象变量其实就是实参变量的引用,所有他们是同一个。 function output(obj) {
obj = Object.assign({}, obj);
obj.count = obj.count + 1;
console.log(obj.count);
} function output(obj) {
obj = JSON.parse(JSON.stringify(obj));
obj.count = obj.count + 1;
console.log(obj.count);
} 以上两种方式都是对形参obj对象重新“复制”一份新的对象。 |
知识点
原因var obj{ //定义一个对象obj,并设定他的属性count 为1
count = 1
}
function f(obj) { //传给函数f 形参obj的其实是obj本体,所以函数内的代码将obj的count属性+1 ,其实是会影响到obj本体的属性的。
obj.count +1
console.log(obj.count)
}
console.log(obj.count) //因为obj的本体属性已经被影响,所以输出的值为2
f (obj) 解题方法var obj{
count = 1
}
function f (obj){
obj=Object.assign({} ,obj) //调用Object.assign()方法将源属性的值复制到目标对象obj。
obj.count+1 //这时候被改变属性的已经不是原来定义的obj了
console.log(obj.count)
} |
在上面代码之后,执行下面代码分别输出什么?
The text was updated successfully, but these errors were encountered: