js this指代详解与分享

一个小小的经验分享

需求:给一个构造器(即构造函数)传入一个对象,通过构造器实例得到的对象访问传入对象的属性;

//创建一个接受properties对象的对象

function User(properties){
//遍历对象属性
for(var i in properties){
//为属性创建获取器
this['get' + i]=function(){
var p = i;
return properties[p];
}
//为属性创建设置器
this['set' + i] = function(val){
var p = i;
properties[p] = val;
}
}
}


var students = new User({age:'22',sex:'man',name:'Mr.smith'});
students.getage();//Mr.smith 我查,怎么回事,居然不是我想要的22,百思不得其姐
// 认真分析后发现,原来是循环出现了问题,实例化的时候回执行构造函数,所以实例的时候情况是这样的
this.['get' + 'age'] = function(){return properties[i]};//给实例得到的对象添加了一个getage属性,但是并没有执行属性的方法
this.['get' + 'sex'] = function(){return properties[i]};
this.['get' + 'name'] = function(){return properties[i]};


students.getage();//执行这个的时候执行对应的方法return properties[i],但是这个时候循环已经结束了,所以i的值永远等于最后一个属性值,所以返回最后一个属性对应的值
//头脑风暴后,我想到了用一个局部变量来存放每个i的值,改进代码如下:
function User(properties){
//遍历对象属性
for(var i in properties){
(function(){//每次循环都执行一个匿名函数,在匿名函数中保存变量i
         var p = i; //把i当前的值赋给p,1.由于外部可以通过['get' + i]方法访问p,所以在匿名函数执行完后不会被释放,2.由于每次循环定义一个匿名函数,也就是说在多个函数定义p变量,所以p变量的值不会相互影响
         //为属性创建获取器
this['get' + i]=function(){
return properties[p];
}
//为属性创建设置器
this['set' + i] = function(val){
properties[p] = val;
}
        console.log(p);
        })();
}
}


// 心里暗暗的佩服了一下自己,太牛逼了,于是开始测试代码
var students = new User({age:'22',sex:'man',name:'Mr.smith'});
students.getage();//什么?getage()is not function,你大爷的再说多一边,再测试了几百遍,还是一样,到底是什么原因呢?




// 转了几百遍,看到this然后想起有个叫上下文的东西,然后仔细分析,i的上下文是对象User函数,而匿名函数里面的this的上下文是window对象,想到这里,秒懂,把
// getage这些属性都加到隔壁老王window对象家里去了,当然在实例students上找不到对应属性啦,于是我去window家里找找
window.getage();//22,我哩个去,终于找到了,但是我们是想搬到我们家去,这个咋整呢?问题所在就是this指向错误了,咱给个正确的this指向不就完了吗,代码如下:
function User(properties){
//遍历对象属性
for(var i in properties){
(function(that){//每次循环都执行一个匿名函数,在匿名函数中保存变量i
         var p = i; //把i当前的值赋给p,1.由于外部可以通过['get' + i]方法访问p,所以在匿名函数执行完后不会被释放,2.由于每次循环定义一个匿名函数,也就是说在多个函数定义p变量,所以p变量的值不会相互影响
         //为属性创建获取器
that['get' + i]=function(){
return properties[p];
}
//为属性创建设置器
that['set' + i] = function(val){
properties[p] = val;
}
        console.log(p);
        })(this);//把this当作参数传递给匿名函数,此时的this指向User函数的实例对象
}
}


var students = new User({age:'22',sex:'man',name:'Mr.smith'});
students.getage();//22
students.getsex();//man


// 到此分享完毕,总结:写js代码最主要的是要充分认识作用域以及上下文,当然还有细心,不然一不小心就被一个低级错误放倒了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值