Q:发现同一个页面退出再进入。this.obj.test还是存在,并没有被销毁。假设之前的页面是page1,进入之后this.obj.test赋值:this.obj.test='test',退出。再进入的页面是page2,打印this.obj.test,结果是'test'。
<button bindtap="onTap">wx切换首页</button>
<button onTap="onTap">dd切换首页</button>
Page({
data: {
logs: []
},
str: '',
num: 0,
flag: false,
arr: [],
obj: {},
onLoad: function() {
console.log("[logs]onLoad:", this)
},
onShow: function() {
console.log("[logs]onShow:", this)
},
onHide: function() {
console.log("[logs]onHide:", this)
},
onUnload: function() {
console.log("[logs]onUnload:", this)
},
onTap: function() {
this.str = 'string-test';
this.num = 100;
this.flag = true;
this.arr = [1, 2, 3];
this.obj.test = 'test';
console.log("[logs]onTap:", this)
console.log("this.hasOwnProperty('obj'):", this.hasOwnProperty('obj'))//wx:true,dd:false
console.log(" 'obj' in this:", 'obj' in this) //wx:true,dd:true
// 是否是原型链上的属性
// function propertyFromPrototype(obj, prop) {
// return !obj.hasOwnProperty(prop) && prop in obj
// }
// console.log(propertyFromPrototype(this, 'obj')) // wx:false,dd:true
}
})
钉钉和微信的差异
平台 | 自身属性 | proto |
---|---|---|
钉钉 | null | arr:[],flag: false,num: 0,obj: {},str: "" |
微信 | arr:[], flag: false,num: 0,obj: {},str: "" | freeData:{arr:[],flag: false,num: 0,obj: {},str: ""} |
赋值操作之后
平台 | 自身属性 | proto |
---|---|---|
钉钉 | arr:[1,2,3],flag: true,num: 100,str: "string-test" | arr:[],flag: false,num: 0,obj: {test:'test'},str: "" |
微信 | arr:[1,2,3],flag: true,num: 100,obj: {test:'test'},str: "string-test" | freeData:{arr:[],flag: false,num: 0,obj: {},str: ""} |
总结:钉钉在实例化对象没有给子对象开辟空间,跟vue Component一样,例子中的obj等一系列都写在了原型链上。
不过基本数据对象(基本类型)在=的时候可以在page1上开辟栈内存,复杂数据对象(引用类型)的属性在=的时候只会在page1的原型链上找到并赋值。所以导致复杂对象会在不同实例化对象(page1和page2)之间共享。
<!--钉钉-->
// 会指向本身,这么写的话就自身就会有obj的属性
// this.obj={
// 'name': 'Tom'
// }
// 等于this.__proto__.obj.name='Tom';
this.obj.name = 'Tom';
小程序中data:{name:'xx'},设置方法是this.setData({name:'xxx'}),设置this.data并不会更新页面内容
vue组件:data(){return{name:'xx'}},设置方法就是this.data.name=xxx
vue组件中是利用函数作用域使得每个实例化对象都拥有了自己的data作用域
猜想:
- 钉钉使用的原型模式创建对象,所有实例共享属性和方法
function Page(){}
Page.prototype.data={};
Page.prototype.str='';
Page.prototype.flag=false;
Page.prototype.arr=[];
Page.prototype.obj={};
var p1=new Page();
var p2=new Page();
p1.obj.test = 'test';
p2.obj.test //'test',p1对obj的修改影响到了p2
- 微信使用的构造函数模式(或者组合构造函数和原型模式)创建对象,所有实例拥有独立的属性副本
function Page(){
this.data={};
this.str='';
this.flag=false;
this.arr=[];
this.obj={};
}
var p1=new Page();
var p2=new Page();
p1.obj.test = 'test';
p2.obj.test //undefined,p1和p2拥有各自的属性副本,互不干扰