分分钟掌握this关键字的指向

1.this的值取决于函数被调用的方式 正常调用指向window 谁调用就指向谁

var objData = {a: 'custom'};

// 这个属性是在global对象定义的
var a = 'global';

function whatsThis() {
    return this.a; // this的值取决于函数的调用方式
}
whatsThis(); // 输出 "global"

2.使用call apply方法可以强制改变this指向

let objData = {a: 'custom'};

// 这个属性是在global对象定义的
let a = 'global';

function whatsThis () {
    return this.a
}
whatsThis.call(objData); // 输出 "custom"

3.ES5中加了 bind 函数名.bind() 将会创建一个与该函数体相同的新函数 这个新函数 不论在哪里调用 this的指向都会指向bind的第一个参数 被永久绑定 这个新的函数体只会被绑定一次

function whatsThis () {
    return this.a;
}
let pointThis = whatsThis.bind({a: 'point'});
pointThis(); // 输出 point

let bindThis = pointThis.bind({a: 'bind'});

bindThis(); // 输出 point

let againBind = whatsThis.bind({a: 'again'});
againBind(); // 输出 again

4.箭头函数内的this 一旦被调用 就永久指向 无法修改 如果只是引用 没有调用 那么调用箭头函数后,this指向window

var a = '全局a';
let foo = (() => this.a);
foo(); // 全局a

let a = '全局a';
let foo = (() => this.a);
foo(); // undefined

let objData = {
    a: 'objData中的a',
    foo:foo
}
objData.foo(); // 全局a

let secondData = {a: 'secondData中的a'}
objData.foo.call(secondData); // 全局a

objData.foo.bind({a: 'bind中的a'});
objData.foo() // 全局a

5.如果一个构造函数具有返回对象的return语句和绑定this的对象 则结果是返回的return 否则 是this 2个都有 返回return 没有return 只有this 则返回this

function foo() {
    this.a = 'foo'
}
let secondFoo = new foo();

secondFoo.a // foo
function foo() {
    this.a = 'foo'
    return {a: 'foo中的第二个a'}
}
let secondFoo = new foo();

secondFoo.a // foo中的第二个a

6.whatsThis中的this分别指向obj和全局  之所以输出内容是whatsThis中的a 因为就近先查找到了a的值

var obj = {a: 'custom'};
var a = 'global';
function whatsThis () {
this.a = 'whatsThis中的a';
return this.a;
}
whatsThis.call(obj); // 输出 whatsThis中的a
var obj = {a: 'custom'};
var a = 'global';
function whatsThis () {
this.a = 'whatsThis中的a';
return this.a;
}
whatsThis(); // 输出 whatsThis中的a

7.在严格模式下,如果 this 没有被执行环境定义,那它将保持为 undefined

function whatsThis() {
    "use strict"; // 这里是严格模式
      return this;
}

whatsThis(); // undefined
function whatsThis() {
    return this;
}

whatsThis(); // Window

8.匿名函数的执行环境具有全局性,因此其this对象通常指向window。

var name = 'The Window';
var object = {
    name: 'My Object',
    getName: function(){
        return function(){
            return this.name
        }
    }
}
console.log(object.getName()()); // 'The Window'

为什么上面例子中返回的是全局的name呢?

是因为每个函数在被调用时都会自动取得2个特殊变量:this和arguments。内部函数在搜索这2个变量时,只会搜索到其活动对象为止。因此永远不可能直接访问外部函数中的这2个变量。

当然如果想访问object的name属性,可以把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。

var name = 'The Window';
var object = {
    name: 'My Object',
    getName: function(){
        var that = this;
        return function(){
            return that.name
        }
    }
}
console.log(object.getName()()); // 'My Object'

如下写法也可以直接返回object中的name

var name = 'The Window';
var object = {
    name: 'My Object',
    getName: function(){
        return that.name;
    }
}
console.log(object.getName()); // 'My Object'
console.log(object.getName)(); // 'My Object'
console.log(object.getName = object.getName)(); // 'The window', 在非严格模式下

上面打印的三组内容,第一行代码返回的是'My Object',因为This.name就是object.name

第二行代码虽然在调用前加了括号,就好像只是在引用一个函数,但this的值得到了维持。因为object.getName和(object.getName)的定义是相同的。

第三行代码先执行了一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以this的值不能得到维持。结果就返回了'The window'

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值