出处:http://www.cnblogs.com/onepixel/p/5036369.html
4、this 关键字
在一个函数中,this总是指向当前函数的所有者对象,this总是在运行时才能确定其具体的指向, 也才能知道它的调用对象。
1
2
3
4
5
6
7
8
|
window.name =
"window"
;
function f(){
console.log(
this
.name);
}
f();
//window
var
obj = {name:
'obj'
};
f.call(obj);
//obj
|
在执行f()时,此时f()的调用者是window对象,因此输出 window
f.call(obj) 是把f()放在obj对象上执行,相当于obj.f(),此时f 中的this就是obj,所以输出的是 obj
5、实战应用
demo1
1
2
3
4
5
6
7
8
9
10
11
|
var
foo =
"window"
;
var
obj = {
foo :
"obj"
,
getFoo : function(){
return
function(){
return
this
.foo;
};
}
};
var
f = obj.getFoo();
f();
//window
|
demo2
1
2
3
4
5
6
7
8
9
10
11
12
|
var
foo =
"window"
;
var
obj = {
foo :
"obj"
,
getFoo : function(){
var
that =
this
;
return
function(){
return
that.foo;
};
}
};
var
f = obj.getFoo();
f();
//obj
|
6、代码解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//demo1:
//执行var f = obj.getFoo()返回的是一个匿名函数,相当于:
var
f = function(){
return
this
.foo;
}
//f() 相当于window.f(), 因此f中的this指向的是window对象,this.foo相当于window.foo, 所以f()返回"window"
//demo2:
//执行var f = obj.getFoo() 同样返回匿名函数,即:
var
f = function(){
return
that.foo;
}
//唯一不同的是f中的this变成了that, 要知道that是哪个对象之前,先确定f的作用域链:f->getFoo->window 并在该链条上查找that,
//此时可以发现that指代的是getFoo中的this, getFoo中的this指向其运行时的调用者,
//从var f = obj.getFoo() 可知此时this指向的是obj对象,因此that.foo 就相当于obj.foo,所以f()返回"obj"
|
一、函数调用,此时this是全局的也就是window
1 var c=function(){ 2 alert(this==window) 3 } 4 c()//true
二、方法调用
var myObj={ value:2, inc:function(num){ alert(this.value+num); } } myobject.inc(1); //结果3,因为this指向myObj
注意:内部匿名函数不属于当前对象的函数,因此this指向了全局对象window
var myObj={ name:'myObject', value:0, increment:function(num){ this.value += typeof(num) ==='number'? num:0; }, toString:function(){ return '[object:'+this.name+'{value:'+this.value+'}]'; }, getInfo:function(){ return (function(){ return this.toString();//内部匿名函数不属于当前对象的函数,因此this指向了全局对象window })(); } } alert(myObj.getInfo());//[object window];
解决方法:
var myObj={ name:'myObject', value:0, increment:function(num) { this.value += typeof(num) ==='number' ? num : 0; }, toString:function() { return '[object:'+this.name+'{value:'+this.value+'}]'; }, getInfo:function(){ var This=this;//先把当前的this指向存起来 return (function(){ return This.toString(); })(); } } alert(myObj.getInfo());//[Object:myObject {value:0}]
三、用new关键字来新建一个函数对象的调用,this指向被绑定到构造函数的实例上
var fn = function (status){ this.status = status; } fn.prototype.get_status = function(){ return this.status; } var test = new fn('my status'); alert(test.get_status);//my status,this指向test
四、apply/call调用
function MyObject(name){ this.name=name ||'MyObject'; this.value=0; this.increment=function(num){ this.value += typeof(num) === 'number' ? num : 0; }; this.toString=function(){ return '[Object:'+this.name+' {value:'+this.value+'}]'; }; this.target=this; } function getInfo(){ return this.toString(); } var myObj=new MyObject(); alert(getInfo.apply(myObj));//[Object:MyObject {value:0}],this指向myObj alert(getInfo.apply(window));//[object Window],this指向window
通过call和apply可以重新定义函数的执行环境,即this的指向,这对于一些应用当中是十分常用的
call,apply, bind 和 this
关于Javascript的this指针,和C++/Java很类似。 我们来看个示例:(这个示例很简单了,我就不多说了)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function
print(text){
document.write(
this
.value +
' - '
+ text+
'<br>'
);
}
var
a = {value: 10, print : print};
var
b = {value: 20, print : print};
print(
'hello'
);
// this => global, output "undefined - hello"
a.print(
'a'
);
// this => a, output "10 - a"
b.print(
'b'
);
// this => b, output "20 - b"
a[
'print'
](
'a'
);
// this => a, output "10 - a"
|
我们再来看看call 和 apply,这两个函数的差别就是参数的样子不一样,另一个就是性能不一样,apply的性能要差很多。(关于性能,可到 JSPerf 上去跑跑看看)
1
2
3
4
5
|
print.call(a,
'a'
);
// this => a, output "10 - a"
print.call(b,
'b'
);
// this => b, output "20 - b"
print.apply(a, [
'a'
]);
// this => a, output "10 - a"
print.apply(b, [
'b'
]);
// this => b, output "20 - b"
|
但是在bind后,this指针,可能会有不一样,但是因为Javascript是动态的。如下面的示例
1
2
3
4
|
var
p = print.bind(a);
p(
'a'
);
// this => a, output "10 - a"
p.call(b,
'b'
);
// this => a, output "10 - b"
p.apply(b, [
'b'
]);
// this => a, output "10 - b"
|
出处:https://www.cnblogs.com/souliid/p/6005675.html
sleep()
function sleep(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}