this是谁和函数在哪定义的和在哪执行的没有半毛钱的关系,如果想判断this就找到函数执行的地方,按照如下五条规律判断this的指向:
1、自执行函数中的this永远是window
//定时器绑定方法中的this是window
window.setTimeout(function(){
this->window
},1000);
//在函数执行传递的回调函数中,一般情况下的this都是window,但是我们可以自己指定里面的this指向问题
ary.sort/forEach/map(function(){
在context没有传递任何值的情况下this->window
},context);
[柯理化函数]
//改变this关键字的bind方法
function bind(context,fn){
var outerArg=Array.prototype.slice.call(arguments,2);
return function(){
var innerArg=Array.prototype.slice.call(arguments,0);
var arg=outerArg.concat(innerArg);
fn.apply(context,arg);
}
}
2、给元素的某一个事件绑定一个方法(DOM0、DOM2事件绑定),在事件触发执行对应方法的时候,方法中的this是当前元素 (在IE6~8中DOM2绑定事件中的this是window)
oDiv.onclick = function () {
//this->oDiv
var _this = this;
function fn() {
console.log(_this); //oDiv
}
fn();//this->window
};
3、看方法执行前面是否有".",没有就是window,有的话,"."前面是谁this就是谁
function Fn(){this.x=100;}
Fn.prototype.getX=function(){console.log(this.x);}
var f=new Fn;
f.getX();//getX->this是f console.log(f.x); 100
f.__proto__.getX();//getX->this是f.__proto__(Fn.prototype) console.log(Fn.prototype.x); undefined
4、在构造函数模式中,我们函数体中的this.xxx=xxx是给当前的实例增加私有的属性和方法呢,这里的this就是当前这个类的一个实例(参考第3条的列子)
5、使用call和apply强制改变this
[非严格模式] 第一个参数不传/传递的是null或者undefined ->this都是window
[严格模式] 第一个参数不传/undefined this->undefined 如果传递的是null this->null
严格模式
"use strict";
1)不能使用arguments.callee和arguments.caller了;并且arguments[0]=100也不在映射到第一个形参上了;
function fn(v){
v=12;
console.log(v);//12
console.log(arguments[0]);//3
console.log(arguments.callee);//函数本身
console.log(arguments.caller);//调用自己
//'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
}
fn(3);
2)不能使用arguments或者eval命名了
var eval="";//Unexpected eval or arguments in strict mode
3)call和apply this的问题
[非严格模式] 第一个参数不传/传递的是null或者undefined ->this都是window
[严格模式] 第一个参数不传/undefined this->undefined 如果传递的是null this->null
4)声明变量必须加var
num=1;//Error:num is not defined
var num2=13;
delete num2;//Delete of an unqualified identifier in strict mode[删除一个不合格的标识符在严格的模式]
5)不允许对象中的属性名重复了
var obj={
name:"cat",
name:"away"
};//Duplicate data property in object literal not allowed in strict mode[在文字对象严格模式不允许重复的数据属性]
6)
var num3=12;
function fn2(){
console.log(this.num3);// Cannot read property 'num3' of null
}
fn2();