在开发中,this多使用在function函数中,也正是由于调用function的对象的不同,才导致了this的指向不同。需要明白(1)、function也是对象;(2)、function执行时是在某个特定的上下文中执行的。
function是对象,对象就有方法,function中最核心的方法是call方法。
举例call使用的方法:
function say(content){
console.log('From '+this+': Hello '+content);
}
say.call('Bob','World');//From Bob: Hello World
分析call用法:(1)、把第二个到最后一个参数作为函数执行时要传入的参数
(2)、把函数执行时的this指向第一个参数
上面例子通过call,让函数执行时的this指向“Bob”,然后把“World”作为参数传入,所有得到那样输出结果
再如:
function say(word){
console.log(word);
}
say('Hello world');//Hello world
通过以上方式转换为call使用
say.call(window,'Hello world');//Hello world
所以如果想知道function中this指代是谁,可以在脑海中做call使用转换
总结:每次看到 funcName(xxx)时,转换funcName.call(window,xxx);当然此处window指代一般情况下this
例1、匿名函数如:
(function say(word){
console.log(word);
})('Hello word');
call转换等价于
(function say(word){
console.log(word);
}).call(window,'Hello word');
例2、对象中函数调用如:
var person={
name:'Bob',
run:function(time){
console.log(this.name+' has been running for over '+time+' minutes');
}
};
person.run(30);//Bob has been running for over 30 minutes
call调用转换等价于
person.run.call(person,30);//Bob has been running for over 30 minutes
如果是
var person={
name:'Bob',
run:function(time){
console.log(this.name+' has been running for over '+time+' minutes');
}
};
var name='Tom';
person.run(30);//Bob has been running for over 30 minutes
person.run.call(window,30);//Tom has been running for over 30 minutes
例3、
var obj={
x:20,
f:function(){
console.log(this.x);
}
};
obj.f();//等价于obj.f.call(obj);//==>20
obj.innerobj={
x:30,
f:function(){
console.log(this.x);
}
};
obj.innerobj.f();//等价于obj.innerobj.f.call(obj.innerobj);//==>30
例4、
var x=10;
var obj={
x:20,
f:function(){
console.log(this.x);
var foo=function(){
console.log(this.x);
};
foo();
}
};
obj.f();//等价于obj.f.call(obj);//==>20 10
上面,obj中f函数中定义的foo,this指代window,而foo作用域在obj.f函数内
如果也想让上面foo函数也输出obj内的x,改写代码如下:
var x=10;
var obj={
x:20,
f:function(){
console.log(this.x);
var that=this;
var foo=function(){
console.log(that.x);
};
foo();
}
};
虽然上面foo 函数的this仍然指向window,但是that取得obj中this,输出的是that.x, 也就是obj中的x。
例5、
var x=10;
var obj={
x:20,
f:function(){
console.log(this.x);
}
};
obj.f();//相当于obj.f.call(obj);//==>20
var fOut=obj.f;
fOut();//相当于fOut.call(window);//==>10
var obj2={
x:30,
f:obj.f
};
obj2.f();//相当于obj2.f.call(obj2);//==>30
this是在执行时才会被确认的
js构造函数
用于构造函数
先看一段代码:
func person(name) { this.name = name;} var caibirdme = new person("deen"); // caibirdme.name == deen
我上面也说了,函数在用作构造函数时同样可以用call方法去代替,那这里怎么代替呢?
这里你又需要明确一点:new constrcut()
是一种创建对象的语法糖
它等价于
function person(name) {
this.name = name;
}
var foo = new person("deen");
//通过new创建了一个对象
//new是一种语法糖,new person等价于
var bar = (function(name) {
var _newObj = {
constructor : person,
__proto__ : person.prototype,
};
_newObj.constructor(name);
// _newObj.constructor.call(_newObj, name)
return _newObj;
})();