确保在同一域中操作包含this的方法和函数。应避免把包含有this的全局函数或者方法动态用在局部作用域的对象中,也避免在不同作用域的对象之间相互引用包含的this的方法或者属性
1.把this作为参数值来调用函数,就可以避免this多变的问题
<input type="button" value="按钮1" οnclick="f()">
<input type="button" value="按钮2" οnclick="f()">
<script>
function f(){
console.log(this.value);;//this指向window
}
</script>
解决方案:把this作为参数值传递
<input type="button" value="按钮1" οnclick="f(this)">
<input type="button" value="按钮2" οnclick="f(this)">
<script>
function f(o){
console.log(o.value);;//this指向当前input对象
}
</script>
2.设计静态的this指针
2.1 如果要确保构造函数的方法在初始化之后方法所包含的this指针不发生变化:在构造函数中把this指针存储在私有变量中,然后在方法中使用私有变量来引用this指针。
function Base(){
var _this=this;//存储 初始化时对象的引用指针
this.m=function(){return _this;}; //返回初始化时对象的引用指针
this.name="Base";
}
function F(){
this.name="F";
}
F.prototype=new Base; //继承基类
var f=new F();
var n=f.m();
console.log(n.name)//Base this始终指向原型对象,而不是子类的实例对象
注意:如果不使用——_this=this,
console.log(n);//F{} this会指向子类构造器
console.log(n.name);//F
2.2对象直接量,调用对象直接量的名称,而不使用this
var o={
name:"this=o",
b:function(){
return o;//返回对象直接量名称,而不是this
}
}
var o1={
name:"this=o1",
b:o.b
}
var a=o1.b();//返回o对象
console.log(a.name);//"this=o"
3.设计静态this的扩展方法
this作为一个动态指针也是可以被转换为静态指针的,实现方法主要是利用Function对象的call()或者apply()
//3.1把this转化为静态指针
Function.prototype.pointTo=funciton(){
var _this=this;
return function(o){
return _this.apply(o,arguments);//返回执行当前函数,并把当前函数的作用域指定到对象o
}
}
var o={name:"this=o"}
o.b=(function(){return this;}).pointTo(o); //把this绑定到o
var o1={name:"this=o1",b:o.b}
var a=o1.b();
console.log(a.name);//'this=o'
扩展new运算符的替代方法,从而间接使用自定义函数实例化类
//3.2把构造函数转化为实例对象
function instanceFrom(f){//f表示传入的构造函数
var a=[].slice.call(arguments,1);//获取构造函数的参数
f.prototype.constructor=f;//手工设置构造函数的原型构造器
f.apply(f.prototype,a);//在原型对象上强制指定构造器,则原型对象就成了构造函数的实例,同时由于它的构造器已经被设置为了构造函数,则此时原型对象就相当于一个构造函数的实例对象
return f.prototype;//返回该原型对象
}
function F(){this.name="Fm"}
var f=instanceFrom(F) //等价于 var f=new F();
console.log(f.name);//Fm
嵌套函数结构体内this的变化
通过函数调用的方式来执行
function f(){
this.a=" a ";//属于window
console.log(this.a+this.b+this.c+this.d);//a undefined undefined undefined
e();//f()函数域内调用,属于window
function e(){
this.b=" b ";
console.log(this.a+this.b+this.c+this.d);// a b c undefined
g();//e()函数域内调用,属于window
function g(){
this.c=" c ";
console.log(this.a+this.b+this.c+this.d);//a undefined undefined undefined
h();//g()函数域内调用,属于window
function h(){
this.d=" d ";
console.log(this.a+this.b+this.c+this.d);// a b c d
}
}
}
}
f();//属于window
通过实例化的方式来激活
function f(){
this.a=" a ";//属于对象f
console.log(this.a+this.b+this.c+this.d);//a undefined undefined undefined
var x=new e();
function e(){
this.b=" b ";//属于对象e
console.log(this.a+this.b+this.c+this.d);//undefined b undefined undefined
var x=new g();
function g(){
this.c=" c ";//属于对象g
//备注:当前作用域没有定义变量a,b,返回undefined,则undefined+undefined=NaN
console.log(this.a+this.b+this.c+this.d);//NaN c undefined
var x=new h();
function h(){
this.d=" d ";//属于对象h
console.log(this.a+this.b+this.c+this.d);//NaN d
}
}
}
}
var x=new f();