资讯专栏INFORMATION COLUMN

JavaScript的this

happyfish / 2727人阅读

摘要:的函数的关键字在中的行为与其他语言稍有不同。严格模态与非严格模态也有一定的区别。在大多数情况下,这个值由函数的调用方式决定。它不能在定义期间通过赋值来确定,而且每次调用函数时它可能是不同的。

Javasctipt 的 this
函数的this关键字在JavaScript中的行为与其他语言稍有不同。严格模态与非严格模态也有一定的区别。在大多数情况下,这个值由函数的调用方式决定。它不能在定义期间通过赋值来确定,而且每次调用函数时它可能是不同的。ES5引入了bind()方法来设置函数this的值,不管它是如何调用的,而ES2015引入了箭头函数,它不提供自己的this绑定(它保留了所包含的词法上下文的这个值)。
一、在全局环境中的this 在浏览器环境中

直接输出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环境中

直接输出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; 注意区分上面的立即执行函数

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102893.html

相关文章

  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0
  • javascript技术难点(三)之this、new、apply和call详解

    摘要:第四点也要着重讲下,记住构造函数被操作,要让正常作用最好不能在构造函数里 4) this、new、call和apply的相关问题 讲解this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,因此本篇打算换一个思路从应用的角度来讲解this指针,从这个角度理解this指针更加有现实意义。 下面我们看看在ja...

    ghnor 评论0 收藏0
  • JavaScript进阶之’this

    摘要:所以相同点是,在全局范围内,全局变量终究是属于老大的。只生效一次引入了。只生效一次在箭头函数中,与封闭词法环境的保持一致。我通常把这些原始函数叫做构造函数。在里面你可以嵌套函数,也就是你可以在函数里面定义函数。 showImg(https://img-blog.csdnimg.cn/20190522000008399.jpg?x-oss-process=image/watermark,...

    shenhualong 评论0 收藏0
  • Javascript 深入浅出This

    摘要:中函数的调用有以下几种方式作为对象方法调用,作为函数调用,作为构造函数调用,和使用或调用。作为构造函数调用中的构造函数也很特殊,构造函数,其实就是通过这个函数生成一个新对象,这时候的就会指向这个新对象如果不使用调用,则和普通函数一样。 this 是 JavaScript 比较特殊的关键字,本文将深入浅出的分析其在不同情况下的含义,可以这样说,正确掌握了 JavaScript 中的 th...

    Y3G 评论0 收藏0
  • 学习React之前你需要知道JavaScript基础知识

    摘要:和类在开始时遇到类组件,只是需要有关类的基础。毕竟,中的条件呈现仅再次显示大多数是而不是特定的任何内容。 在我的研讨会期间,更多的材料是关于JavaScript而不是React。其中大部分归结为JavaScript ES6以及功能和语法,但也包括三元运算符,语言中的简写版本,此对象,JavaScript内置函数(map,reduce,filter)或更常识性的概念,如:可组合性,可重用...

    bitkylin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<