Q:發(fā)現(xiàn)同一個(gè)頁(yè)面退出再進(jìn)入。this.obj.test還是存在,并沒(méi)有被銷毀。假設(shè)之前的頁(yè)面是page1,進(jìn)入之后this.obj.test賦值:this.obj.test='test',退出。再進(jìn)入的頁(yè)面是page2,打印this.obj.test,結(jié)果是'test'。
<button bindtap="onTap">wx切換首頁(yè)</button>
<button onTap="onTap">dd切換首頁(yè)</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
}
})
釘釘和微信的差異
| 平臺(tái) | 自身屬性 | proto |
|---|---|---|
| 釘釘 | null | arr:[],flag: false,num: 0,obj: {},str: "" |
| 微信 | arr:[], flag: false,num: 0,obj: {},str: "" | freeData:{arr:[],flag: false,num: 0,obj: {},str: ""} |
賦值操作之后
| 平臺(tái) | 自身屬性 | 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: ""} |
總結(jié):釘釘在實(shí)例化對(duì)象沒(méi)有給子對(duì)象開(kāi)辟空間,跟vue Component一樣,例子中的obj等一系列都寫(xiě)在了原型鏈上。
不過(guò)基本數(shù)據(jù)對(duì)象(基本類型)在=的時(shí)候可以在page1上開(kāi)辟棧內(nèi)存,復(fù)雜數(shù)據(jù)對(duì)象(引用類型)的屬性在=的時(shí)候只會(huì)在page1的原型鏈上找到并賦值。所以導(dǎo)致復(fù)雜對(duì)象會(huì)在不同實(shí)例化對(duì)象(page1和page2)之間共享。
[ JS 進(jìn)階 ] 基本類型 引用類型 簡(jiǎn)單賦值 對(duì)象引用
<!--釘釘-->
// 會(huì)指向本身,這么寫(xiě)的話就自身就會(huì)有obj的屬性
// this.obj={
// 'name': 'Tom'
// }
// 等于this.__proto__.obj.name='Tom';
this.obj.name = 'Tom';
小程序中data:{name:'xx'},設(shè)置方法是this.setData({name:'xxx'}),設(shè)置this.data并不會(huì)更新頁(yè)面內(nèi)容
vue組件:data(){return{name:'xx'}},設(shè)置方法就是this.data.name=xxx
vue組件中是利用函數(shù)作用域使得每個(gè)實(shí)例化對(duì)象都擁有了自己的data作用域
猜想:
- 釘釘使用的原型模式創(chuàng)建對(duì)象,所有實(shí)例共享屬性和方法
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對(duì)obj的修改影響到了p2
- 微信使用的構(gòu)造函數(shù)模式(或者組合構(gòu)造函數(shù)和原型模式)創(chuàng)建對(duì)象,所有實(shí)例擁有獨(dú)立的屬性副本
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擁有各自的屬性副本,互不干擾