javascript中this使用场景的总结

首先需要明确的是函数中写的this只有在调用的时候,我们才能确定它的值是怎样的。因为函数调用时会生成一个新的执行上下文环境。

作为普通函数或全局函数调用

在全局作用域下,调用普通函数,浏览器端其this指向window。node中指向global。

var n = 'hello world !';   
function example(){     
    this.n = 0;   
 }  
console.log(n); // 0 !

另外需要注意一点,在严格模式下,未指定环境对象而调用函数,this的值是undefined。

作为构造函数调用

若直接调用该构造函数,与普通函数无区别,上面已经讲述。若是使用它创建对象,那么其中的this值会指向该新对象。

function Foo(){
    this.x = 10;
    console.log(this);    //Foo {x:10}
}
var foo = new Foo();
console.log(foo.x);      //10

作为对象的方法调用

如果函数作为对象的方法时,方法中的 this 指向该对象。

var obj = {
    x: 10,
    foo: function () {
        console.log(this);        //Object
        console.log(this.x);      //10
    }
};
obj.foo();

若是不作为对象方法调用结果会是window。

var obj = {
    x: 10,
    foo: function () {
        console.log(this);        //Window
        console.log(this.x);      //undefined
    }
};
var fn = obj.foo;
fn();

还有一种情况需要注意:

var obj = {
    x: 10,
    foo: function () {
        function f(){
            console.log(this);      //Window
            console.log(this.x);    //undefined
        }
        f();
    }
}
obj.foo();

函数 f 虽然是在 obj.foo 内部定义的,但它仍然属于一个普通函数,this 仍指向 window。
在这里,如果想要调用上层作用域中的变量 obj.x,可以使用缓存外部 this 变量的方法。

var obj = {
    x: 10,
    foo: function () {
        var self = this;
        function f(){
            console.log(self);      //{x: 10}
            console.log(self.x);    //10
        }
        f();
    }
}
obj.foo();

构造函数 prototype 属性

function Foo(){
    this.x = 10;
}
Foo.prototype.getX = function () {
    console.log(this);        //Foo {x: 10, getX: function}
    console.log(this.x);      //10
}
var foo = new Foo();
foo.getX();

在 Foo.prototype.getX 函数中,this 指向的 foo 对象。不仅仅如此,即便是在整个原型链中,this 代表的也是当前对象的值。这点需要注意。

用call、apply、bind调用

当一个函数被call、apply和bind调用时,this的值就取传入的对象的值。

var obj = {
    x: 10
}
function foo(){
    console.log(this);     //{x: 10}
    console.log(this.x);   //10
}
foo.call(obj);

有一点需要注意,就是若没有传入对象,即call或apply参数为空,此时默认为传入全局对象。

var obj = {
    x: 10
}
var x = 9;
function foo(){
    console.log(this);     //window
    console.log(this.x);   //9
}
foo.call();

apply与call只是传入参数写法不同,不再举例。
举例说明一下bind,也是可以改变作用域的,只要将传入的对象绑定到函数上即可。注意一下其调用方式。

var obj = {
    x: 10
}
function foo(){
    console.log(this);     //{x: 10}
    console.log(this.x);   //10
}
foo.bind(obj)();

箭头函数

它的this指向与普通函数有很大的不同。箭头函数内部的 this 是词法作用域,由上下文确定。简单说就是箭头函数中的 this 只和定义它时候的作用域的 this 有关,而与在哪里以及如何调用它无关,同时它的 this 指向是不可改变的。

var obj = {
    x: 10,
    foo: function() {
        var fn = () => {
            return () => {
                return () => {
                    console.log(this);      //Object {x: 10}
                    console.log(this.x);    //10
                }
            }
        }
        fn()()();
    }
}
obj.foo();

对于箭头函数还需要注意一点,就是它的this确定后不会改变。使用call、apply、bind也无法改变它的this,因此使用它们传入的第一个参数无效。但是后面添加的参数值还是有效的。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值