如下代码:
function Boy() {};
Boy.prototype.grow = function () {
this.year++;
this.girlfriend.push('hands');
console.log(this.girlfriend);
console.log(this.year);
};
Boy.prototype.year = 18;
Boy.prototype.girlfriend = [];
var me = new Boy();
me.grow();
me.grow();
var you = new Boy();
you.grow();
输出是
[ 'hands' ]
19
[ 'hands', 'hands' ]
20
[ 'hands', 'hands', 'hands' ]
19
以下是我的心路历程:
求高人指点。
1
geelaw 2017-08-08 00:05:49 +08:00
|
2
KeepPro 2017-08-08 00:13:22 +08:00 via Android
我记着 prototype 是一个指针来着。然后这个应该是 js 的两种 值引用和地址引用 造成的区别吧。
|
4
CDL 2017-08-08 00:21:55 +08:00
因为你只是改变的实例的值,并不会影响到原型的初始值
|
5
paledream OP @CDL 实例在初始化时,将原型中的非引用属性复制到了实例中,这个意思吗?
构造函数中并没有 year 这个属性,调用 grow 函数时应该是去原型里去寻找 year 呀 |
7
momocraft 2017-08-08 00:37:54 +08:00
基礎類型都是 immutable 的, 而且 equality 即 identity. 此時其實無所謂是不是"共享", 因為無法區分.
this.year++; 這句從 prototype 讀, 然後寫到了 instance. 即你說的 "this 指针将 year 复制到了实例内部?" |
8
FrankFang128 2017-08-08 00:46:19 +08:00
console.dir(me)
console.dir(you) |
9
FrankFang128 2017-08-08 00:58:33 +08:00
|
10
geelaw 2017-08-08 01:02:01 +08:00
@paledream 你可以认为基础类型按值传递,也可以认为基础类型不可变,这两个效果是一样的。
简单地说,无论是 year 是一个指向 int const 的指针,还是就是 int,没有区别。 除非你是开发 JS 解释器的,否则你可以忘记这两者的区别,而去抽象地理解。 |
11
M3oM3oBug 2017-08-08 01:25:10 +08:00 via Android
如果需要达到实例共享同一个属性,可以创建一个立即执行的匿名函数,也就是一个闭包,里面包含的私有属性可以被共享到
|
12
CDL 2017-08-08 09:05:26 +08:00
@paledream 实例上没有定义的值会到原型上去查找,实例定义的值会覆盖原型的值,就跟作用域相似,后面数组的值会变是因为 js 的数组和对象是引用值,修改的话就会直接影响到原型的值了
|
13
jevirs 2017-08-08 09:30:07 +08:00
可是你的代码好污啊。。
|
14
SuperMild 2017-08-08 09:37:57 +08:00 via iPhone
没仔细看,但看见有 this 就觉得头大,JS 能用闭包解决的问题就尽量不要用 this
|
15
bojackhorseman 2017-08-08 09:56:27 +08:00 1
我运行了下你的代码发现,在你执行`me.grow()`时,此时的`this`指向实例本身,相当于`me.year=year+1`,会在`me`上创建一个属性`year`,这是一个 实例属性`me.year`,而你新创建的实例`you`上并没有`you.year`这个属性,所以会去它的`__.proto__`(也就是 Boy.prototype )上找,然后`year`就是 18。不知道是不是这样理解的。
|
16
stzz 2017-08-08 09:56:57 +08:00 1
代码是挺污的....
一般情况下只有在创建情况下才能设置 prototype 的值. 第一次执行 this.year++; 时, 就是 this.year=this.year+1, 右边是继承查找到的值,左边相当于 this.year=19 设置一个本地属性,形成属性遮蔽.. |