javascript中this使用场景的总结

来源:互联网 发布:萌拍相机软件 编辑:程序博客网 时间:2024/06/09 16:08

首先需要明确的是函数中写的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,因此使用它们传入的第一个参数无效。但是后面添加的参数值还是有效的。