问题
前端里面的this指向问题,JavaScript中的this并不总是指向其对象本身。其指向是可以改变的(根据执行的上下文变化而变化)。这里用几个例子来说明(已验证)
例子
<script>
var greeting="welcome";
function sayHello(user){
console.log(this.greeting+","+user);
}
sayHello("xiaoming"); // welcome,xiaoming
//相当于执行window.sayHello() 而window就是他的上文 即this=window
</script>
<script>
var greeting="welcome";
function sayHello(user){
this.greeting="hello"; //加了这一句 代表重新更改了this.greeting的值,但是this依然指向window
console.log(this.greeting+","+user);
}
sayHello("xiaoming"); // hello,xiaoming
</script>
<script>
var greeting="welcome";
function sayHello(user){
console.log(this.greeting+","+user);
}
var obj={
greeting:"hello",
user:"xiaojun",
sex:"male",
sayHello:sayHello
}
obj.sayHello("xiaohong"); //hello,xiaohong
// 前文是obj 所以this指向的是this 即this=obj
</script>
<script>
var greeting="welcome";
var obj={
greeting:"hello",
user:"xiaojun",
sex:"male",
sayHello:function(){
setTimeout(function(){console.log(this.greeting)},2000); //注意setTimeOut里面加function(){} 才是正确写法
}
}
obj.sayHello(); //"welcome"
// setTimeout之间的函数 是异步执行的 。
//等所有任务执行完后 才会回调sayhello函数执行,此时已经跳出obj对象。
//变成 window.sayHello();
</script>
构造函数里的this
- 通过 “new 构造函数” 会创建一个新的对象object
- 而此时将新的对象将设置为函数中的this
<script>
var greeting="hello";
function Fn(){
this.username = "小明";
}
console.log(Fn.greeting ); //undefined
console.log(Fn.username ); //undefined
var zr = new Fn();
console.log(zr.username ); //小明
console.log(Object.prototype.toString.call(zr)); //object
console.log(Object.prototype.toString.call(Fn)); //function
</script>
<script>
var greeting="hello";
function Fn(){
this.username = "小明";
console.log(this.username);
console.log(this.greeting);
}
Fn(); //小明 hello => 相当于window.Fn()
var zr = new Fn(); //小明 undefined => 此时this已经绑定到zr这个对象上了
zr.greeting="weclome"
console.log(zr.greeting ); //weclome
console.log(zr.username ); //小明
console.log(Object.prototype.toString.call(zr)); //object
console.log(Object.prototype.toString.call(Fn)); //function
</script>
bind
利用bind函数可以手动改变this指向,并生成一个新的函数。
关于bind:添加链接描述
关于call apply和bind的区别:这篇文章
bind的基本形式(用法)
bind() 用于将函数(即f)内的this指向目标对象(bind的第一个参数,即这里的obj),并生成新的函数newFun
let newFun=f.bind(obj);
//可以理解为obj.f() 即将f的this指向改为obj
//并生成了新的函数 newFun
bind修改this指向
<script>
var greeting="welcome";
function sayHello(user){
console.log(this.greeting+","+user);
}
var obj={
greeting:"hello",
user:"xiaojun",
sex:"male",
objSayHello:sayHello
}
sayHello("xiaohong"); //welcome,xiaohong
let newFun=sayHello.bind(obj); //把"window.sayHello()" 改成"obj.sayHello()"
newFun("xiaohong"); //hello,xiaohong
</script>
<script>
var greeting="welcome";
var obj={
greeting:"hello",
user:"xiaojun",
sex:"male",
sayHello:function(){
setTimeout(function(){console.log(this.greeting)}.bind(this),2000);
}
}
//此时的obj.sayHello()在执行时已经跳出obj,但是其this已经obj进行了绑定
obj.sayHello(); //"hello"
</script>