JavaScript的this

Javasctipt 的 this

函数的this关键字在JavaScript中的行动与其他言语稍有差别。严厉模态与非严厉模态也有肯定的辨别。在大多数情况下,这个值由函数的挪用体式格局决议。它不能在定义时期经由过程赋值来肯定,而且每次挪用函数时它多是差别的。ES5引入了bind()要领来设置函数this的值,不论它是怎样挪用的,而ES2015引入了箭头函数,它不供应本身的this绑定(它保留了所包括的词法高低文的这个值)。

一、在全局环境中的this

在浏览器环境中

  1. 直接输出this
console.log(this); // Window
console.log(this === window); // true
console.log(this === Window); // false
window instanceof Window // true

上述效果说明直接输出this时,输出的是它的组织函数,但它实际上是一个实例;

'use strict'
console.log(this); // undefined

严厉情势下,全局的this指向undefined

在node环境中

  1. 直接输出this
console.log(this); // {}

严厉和非严厉情势都是 {}

二、函数中的this

直接在全局环境中挪用,而不是作为某个对象的属性或要领

function fn() {
    return this;
}
let obj = {
    a: 1,
    b: fn
}
fn() // node: global , browser: window
let objFn = obj.b;
objFn(); // node: global , browser: window

// 箭头函数
let obj2 = {
    a: 2,
    b: () => this
}
let obj2Fn = obj2.b;
obj2Fn(); // node: global , browser: window

// 马上实行函数
!function(){
    console.log(this === window) // true
}()

let obj = {
    say: function() {
        console.log(this === window) // true
    }()
}
obj.say;

let str = 'windows'
let o = {
    str: 'o',
    methods: {
        str: 'methods',
        fn: function () { console.log(this.str) },
           arrowFn: function() { // IIFE
          let fn = () => { console.log(this.str) } 
          return fn;
           }()
    }
}
o.methods.arrowFn(); // undefined ;此时,this指window;而用let声明的str变量不会添加到window对象上去,所认为undefined;

在严厉情势下

function fn() {
    'use strict'
    return this;
}
fn() // undefined

作为对象的属性挪用

function fn() {
    return this;
}
let obj1 = {
    a: 1,
    b: fn
}
let obj2 = {
    a: 2
}
obj2.b = obj1.b;
obj1.b(); // {a: 1, b: ƒn}
obj2.b(); // {a: 2, b: ƒn}

// 箭头函数
let obj1 = {
    a: 1,
    b: () => this
}
let obj2 = {
    a: 2
}
obj2.b = obj1.b;
obj1.b(); // node: global , browser: window
obj2.b(); // node: global , browser: window

经由过程call 和 apply 要领挪用

假如函数在其主体中运用this关键字,则可以运用call()或apply()要领将其值绑定到挪用的特定对象

function add(c, d) {
  return this.a + this.b + c + d;
}

var o = {a: 1, b: 3};

add.call(o, 5, 7); // 16

add.apply(o, [10, 20]); // 34

// 经常使用的例子
function bar() {
  console.log(Object.prototype.toString.call(this));
}

bar.call(7);     // [object Number]
bar.call('foo'); // [object String]

经由过程 bind 要领来绑定this

function fn() {
    return this.a;
}

let k = fn.bind(null);
k(); // undefined
//此时this === window

let g = fn.bind({a: 1});
g(); // 1

let m = fn.bind({a: 2});
m(); // 2

let h = g.bind({a: 3}); // bind只会绑定一次
h(); // 1

// 一般返回值
let obj = {
    a: 1,
    say: (function() {
        let _say = function() {
            console.log(this.a);
        }
        return _say;
    })()
}
obj.say(); // 1

// bind obj
var obj = {
    say: (function() {
        let _say = function() {
            console.log(this === window);
        }
        return _say.bind(obj);
    })()
}
obj.say(); // true



// bind的简朴完成
Function.prototype.myBind = function(context){
  self = this;  //保留this,即挪用bind要领的目的函数
  return function(){
      return self.apply(context,arguments);
  };
};

let g1 = fn.myBind({a: 1})
g1(); // 1
let h1 = g1.myBind({a: 3})
h1(); // 报错,

道理

this指的是函数运转时地点的环境,实行高低文

JavaScript 将对象存储在内存中,会将存储的地点赋给我们所说明的变量;

var o = {a: 5};
//内存中会如许存储 o => a => {
//  foo: {
//    [[value]]: 5
//    [[writable]]: true
//    [[enumerable]]: true
//    [[configurable]]: true
//  }
//}

var f = function () {}
var m = {a: f} 
// 当a的值是一个函数的时刻,就会变成以下情势:
//内存中会如许存储 o => a => {
//  foo: {
//    [[value]]: f的地点
//    [[writable]]: true
//    [[enumerable]]: true
//    [[configurable]]: true
//  }
//}

this的作用

由上面可以看出,因为函数零丁存储,可以零丁运转,运转在差别的高低文中。但要有一个机制来示意它,this就是这个作用,可以指向当前函数的运转环境;

箭头函数道理的思索

箭头函数又和上文说的内容不符合。实在细致想一想,它是个语法糖,等同于给函数运用了bind要领,绑定函数的父作用域实行环境

let str = 'windows'
let o = {
    str: 'o',
    methods: {
        str: 'methods',
        fn: function () { console.log(this.str) },
           arrowFn: () => { console.log(this.str) } 
    }
}

let str = 'windows'
let o = {
    str: 'o',
    methods: {
        str: 'methods',
        fn: function () { console.log(this.str) },
           arrowFn: function() {
          let fn = () => { console.log(this.str) } 
          return fn;
           }
    }
}

o.methods.fn(); // methods
o.methods.arrowFn()(); // methods; 注重辨别上面的马上实行函数
    原文作者:Holever
    原文地址: https://segmentfault.com/a/1190000018628113
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞