s= {
"a":111
}
ss = {
"sss" : {
"set":function(num){
this.a=num
return this
},
"a":222
}
}
Object.setPrototypeOf(ss.sss, s);
alert(new ss.sss.set(333).a+'--'+new ss.sss.set(555).a);
alert(ss.sss.set(333).a+'--'+ss.sss.set(555).a);
1.两个alert的执行结果为什么是一样的呢?
2.为什么new 和没new 一样呢?
3.没new是一个独立的对象吗?
4.如果效果一样,没用new是不是更省内存呢?
答案公布,因为函数里有return返回对象了,所以不需要new,如果写new 就不必返回对象,重复了!还有没new的和new的一样,没有哪个更省内存,因为new包括了return 对象就真么简单,感谢问题下面的评论者的链接
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
new ss.sss.set(333).a和new ss.sss.set(555).a这两个操作, 得到的this不是ss对象, 而是set的实例. 这里的this.__proto__ === ss.sss.set.prototype. 这里的this.a与ss.sss无关, 是新实例的this.a. 返回新实例, 访问其a属性, 就会得到刚才设置的a属性.ss.sss.set(333).a和ss.sss.set(555).a这两个操作, 因为没有使用new, 所以这里的this指向的是ss.sss, 所以修改的是ss.sss.a. 因为ss.sss.set返回的是this, 所以这里的ss.sss.set(333).a实际上就是ss.sss.a.综上, 实际上你两种方式(用或不用
new), 得到的对象并不是同一个对象, 而是不同的对象.set函数内部有return this;用new调用时返回的是set的实例,实例中有a属性,函数调用时this指向时sss,返回的是sss,是在sss中创建了a属性,已经改变了sss。
就代码来讲:
后面的
alert你应该是懂的,第一个的话,new ss.sss.set(333),返回一个set { a:333 },故自然是333了。我理解题主在想什么,但你的DEMO无法体现,因为
new ss.sss.set实例的是set函数,所以不管new不new都无法达到你想要的结果,包括Object.setPrototypeOf(ss.sss, s);也是一句摆设;题主可以加一句代码,你就明白这个错误了。但也不是都无法解释你的四个问题。
首先,不管
s还是ss他们都是一个 Object 类型,而对于 Object 类型是无法被构造的,我想你在写这个DEMO的时候,应该也尝试写了new ss.sss()吧,然后实在没办法了,才写了new ss.sss.set()。以上的回答,从侧面解释你的前三个问题。
而对于,后一个问题,涉及到关于
new后面做了哪些事?以下面代码为准的情况下:
创建一个实例的时候会两个过程:
1、构造
User函数的时候,会把u以传参的形式传递给构造函数,并替换this。2、设置原型链。
精妙之处在于原型链,当然,其中一个好处与你说的一样,更内存;但,这还包括更省代码、更奇妙!
以上。
这样就知道this的指向了,第一个是set,第二个是sss,sss原型链上有a属性,因为Object.setPrototypeOf(ss.sss, s);
new ss.sss.set(333).a和new ss.sss.set(555).a)中,因为是new操作,所以这里set的调用是构造函数的调用,this指向一个新的实例,该实例中的a在构造函数中被赋值,set return出来的this是这个实例。ss.sss.set(333).a和ss.sss.set(555).a)中,set是作为对象中方法来调用,this指向的是调用他的对象sss,方法体中给this.a赋值也就是修改了sss对象的a属性,return出来的是this是sss。因为set方法体中为this.a赋值,而return的又是this,那之后链式获取a,两次alert当然也就和你方法体中赋给a的值也就是你传入的参数都一样了