JS中 this指向的问题
知识点补充:
1.在严格版中的默认的this不再是window,而是undefined。
2.new操作符会改变函数this的指向问题。
function Fn(){
this.num = 1;
}
var a = new Fn();
console.log(a.num); //1
为什么this会指向a?首先new关键字会创建一个空的对象实例a,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。
重点难点
this的指向在函数定义的时候是确定不了的,只有函数执行 的时候才能确定this到底指向谁,实际上 this的最终指向的是那个调用它的对象
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
一、全局作用域中
this在全局作用域中指window。
//全局作用域中
console.log(this)//window
a =1;
console.log(this.a) //相当于window.a 1
//普通函数中
function fn(){
console.log(this)
}
fn()//window
二:闭包中指window
示例1
function fn(){
function fn2(){
console.log(this)
}
return fn2
}
fn()() //window
示例2
var myObject = {
foo:"bar",
func: function() {
var self = this;
console.log("1",this.foo); // bar
console.log("2",self.foo);// bar
(function (){
console.log("3",this.foo); //此处this指向window undefined
console.log("4",self.foo); // bar
}());
}
}
myObject.func();
三:函数调用模式:谁调用就指谁
这里obj.fn()是obj去调用fn,而obj.name=”b”,所以this.name=”b”;
而var fn=obj.fn的时候,fn是window.fn,因此fn()的结果是”a”.
注意:this指向的是上一级调用它的对象,比如obj.fn()与window.obj.fn()都是输出b.
var name="a"
var obj ={
name:'b',
fn:function () {
console.log(this.name)
}
}
obj.fn() //b
var fn=obj.fn
fn() //a
四:构造函数中,this指实例对象。
function Person(name,age) {
this.name=name;
this.age=age;
}
Person.prototype.sayHi=function () {
console.log('I am '+this.name+',I am '+this.age+' years old.')
}
var p1=new Person('张三',20)
p1.sayHi() //I am 张三,I am 20 years old.
补充:当this碰到return时
示例1
function fn() {
this.user = '追梦子';
return {};
}
var a = new fn;
console.log(a.user); //undefined
示例2
function fn() {
this.user = '追梦子';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
示例3
function fn() {
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子
示例4
function fn() {
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a.user); //追梦子
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
示例5
function fn() {
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a); //fn {user: "追梦子"}
还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。
示例6
function fn() {
this.user = '追梦子';
return null;
}
var a = new fn;
console.log(a.user); //追梦子
五:apply/call改变this的指向
在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
主要区别为:apply的第二个参数是散列分布,call则可以是一个数组
六:定时函数中:this指向window
var name = 'window';
var obj = {
name: 'obj',
fn: function () {
var timer = null;
clearInterval(timer);
timer = setInterval(function () {
console.log(this.name); //window
}, 1000)
}
}
七:bind改变this指向
var name = 'window';
var obj = {
name: 'obj',
fn: function () {
var timer = null;
clearInterval(timer);
timer = setInterval(function () {
console.log(this.name); //obj
}.bind(this), 1000)
}
}
bind()的作用类似call和apply,都是修改this指向。但是call和apply是修改this指向后函数会立即执行,
而bind则是返回一个新的函数,它会创建一个与原来函数主体相同的新函数,新函数中的this指向传入的对象。
也因此call/apply不适用于定时函数改变this指向
八:ES6箭头函数:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42
参考连接 http://www.fly63.com/article/detial/904
https://www.cnblogs.com/pssp/p/5216085.html