理解 this 关键字
this 概念
this指向code对象:
var cody = {
living:true,
age:23,
gender:'male',
getGender:function(){return this.gender;}
};
console.log(cody.getGender()); // logs 'male'
Just remember that, in general, this is used inside of functions to refer to the object the function is contained within, as opposed to the function itself (exceptions include using the new keyword or call() and apply()).
请记住一点,通常来说,除了new、call、apply三种特殊情况,其它均指向包含这个function的对象
改变作用域this的指向:
var first_object = {
num: 42
};
var second_object = {
num: 24
};
function multiply(mult) {
return this.num * mult;
}
multiply.call(first_object, 5); // returns 42 * 5
multiply.call(second_object, 5); // returns 24 * 5
bind返回一个Function,你可以一会儿使用它,而不是立马的调用。使用bind之后
var first_object = {
num: 42
};
var second_object = {
num: 24
};
function multiply(mult) {
return this.num * mult;
}
Function.prototype.bind = function(obj) {
var method = this,
temp = function() {
return method.apply(obj, arguments);
};
return temp;
}
var first_multiply = multiply.bind(first_object);
first_multiply(5); // returns 42 * 5
var second_multiply = multiply.bind(second_object);
second_multiply(5); // returns 24 * 5
1. global object: window 全局对象
<script type="text/javascript">//<![CDATA[
alert("我在全局环境下执行");
setTimeout(function () {
alert("我不在全局环境下执行");
}, 1);
//]]></script>
1. 事件一
function click_handler() {
alert(this); // alerts the window object
}
<button id='thebutton' onclick='click_handler()'>Click me!</button>
2. 事件二
显示的不是Window,而是DOM node
function click_handler() {
alert(this); // alerts the button DOM node
}
function addhandler() {
document.getElementById('thebutton').onclick = click_handler;
}
window.onload = addhandler;
<button id='thebutton'>Click me!</button>
2. 进入 eval 代码
2.1 直接调用 eval(),this未改变,eval()
2.2 间接调用,如果是在全局环境下就会被设置成 global 全局对象
什么叫做间接调用:
(0, eval)
var indirectEval = eval;
indirectEval();
3. 进入 function 代码
3.1 在对象上调用
obj.myMethod()
obj["myMethod"]()
this就会指向obj,其它大多数情况下均是指向global object,除了ECMAScript 5规定的8个可以改变this的函数:
Function.prototype.apply( thisArg, argArray )
Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
Array.prototype.every( callbackfn [ , thisArg ] )
Array.prototype.some( callbackfn [ , thisArg ] )
Array.prototype.forEach( callbackfn [ , thisArg ] )
Array.prototype.map( callbackfn [ , thisArg ] )
Array.prototype.filter( callbackfn [ , thisArg ] )
在Function.prototype中,this并没有绑定在function对象上,取而代之的是指向了thisArg参数。
在Array.prototype中,如果提供了thisArg,那么this就会设置成thisArg,如果没有,那么就会设置成global object
上述规则只是适用于plain javascript,当你使用JavaScript库的时候,你会知道许多库都自己控制this的值,他们之所以这么做,就是为了提供最常用的操作。怎么操作this的值呢?
function doWork(callbackfn, thisArg) {
//...
if (callbackfn != null) callbackfn.call(thisArg);
}
4. 还有一种情况,就是new关键字的时候,这个创建完毕之后this默认指向你所创建的这个对象
测试
1. 测试一(面试的时候考到了)
var length = 10;
function fn() {
console.log( this.length );
}
var obj = {
length: 5,
method: function() {
fn();
arguments[0]();
}
}
obj.method(fn, 1);
最终结果是10和2
2. 测试二
if (true) {
// Line A
}
// 答案是 window
3. 测试三
var obj = {
someData: "a string"
};
function myFun() {
// Line B
}
obj.staticFunction = myFun;
obj.staticFunction(); // 答案是 obj
4. 测试四
var obj = {
myMethod : function () {
// Line C
}
};
var myFun = obj.myMethod;
myFun(); // 答案是 window
5. 测试五
function myFun() {
// Line D
}
var obj = {
myMethod : function () {
eval("myFun()");
}
};
obj.myMethod(); // 答案是 window
</script>
谁执行了eval,是obj,但是eval内部,谁执行了myFun,没有,所以为window
6. 测试六
function myFun() {
// Line E
}
var obj = {
someData: "a string"
};
myFun.call(obj); // 答案是 obj
7. 测试七
var foo = {
func1:function(bar){
bar(); //logs window, not foo
console.log(this);//the this keyword here will be a reference to foo object
}
};
foo.func1(function(){console.log(this)});
8. 测试八
var myObject = {
func1:function() {
console.log(this); //logs myObject
varfunc2=function() {
console.log(this); //logs window, and will do so from this point on
varfunc3=function() {
console.log(this); //logs window, as it’s the head object
}();
}();
}
};
myObject.func1();
How does the “this” keyword work? Fully Understanding the this Keyword Scope in JavaScript