资讯专栏INFORMATION COLUMN

JavaScript的this

happyfish / 2870人阅读

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

Javasctipt 的 this

</>复制代码

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

直接输出this

</>复制代码

  1. console.log(this); // Window
  2. console.log(this === window); // true
  3. console.log(this === Window); // false
  4. window instanceof Window // true

上述结果说明直接输出this时,输出的是它的构造函数,但它其实是一个实例;

</>复制代码

  1. "use strict"
  2. console.log(this); // undefined

严格模式下,全局的this指向undefined

在node环境中

直接输出this

</>复制代码

  1. console.log(this); // {}

严格和非严格模式都是 {}

二、函数中的this 直接在全局环境中调用,而不是作为某个对象的属性或方法

</>复制代码

  1. function fn() {
  2. return this;
  3. }
  4. let obj = {
  5. a: 1,
  6. b: fn
  7. }
  8. fn() // node: global , browser: window
  9. let objFn = obj.b;
  10. objFn(); // node: global , browser: window
  11. // 箭头函数
  12. let obj2 = {
  13. a: 2,
  14. b: () => this
  15. }
  16. let obj2Fn = obj2.b;
  17. obj2Fn(); // node: global , browser: window
  18. // 立即执行函数
  19. !function(){
  20. console.log(this === window) // true
  21. }()
  22. let obj = {
  23. say: function() {
  24. console.log(this === window) // true
  25. }()
  26. }
  27. obj.say;
  28. let str = "windows"
  29. let o = {
  30. str: "o",
  31. methods: {
  32. str: "methods",
  33. fn: function () { console.log(this.str) },
  34. arrowFn: function() { // IIFE
  35. let fn = () => { console.log(this.str) }
  36. return fn;
  37. }()
  38. }
  39. }
  40. o.methods.arrowFn(); // undefined ;此时,thiswindow;而用let声明的str变量不会添加到window对象上去,所以为undefined

在严格模式下

</>复制代码

  1. function fn() {
  2. "use strict"
  3. return this;
  4. }
  5. fn() // undefined
作为对象的属性调用

</>复制代码

  1. function fn() {
  2. return this;
  3. }
  4. let obj1 = {
  5. a: 1,
  6. b: fn
  7. }
  8. let obj2 = {
  9. a: 2
  10. }
  11. obj2.b = obj1.b;
  12. obj1.b(); // {a: 1, b: ƒn}
  13. obj2.b(); // {a: 2, b: ƒn}
  14. // 箭头函数
  15. let obj1 = {
  16. a: 1,
  17. b: () => this
  18. }
  19. let obj2 = {
  20. a: 2
  21. }
  22. obj2.b = obj1.b;
  23. obj1.b(); // node: global , browser: window
  24. obj2.b(); // node: global , browser: window
通过call 和 apply 方法调用

</>复制代码

  1. 如果函数在其主体中使用this关键字,则可以使用call()或apply()方法将其值绑定到调用的特定对象

</>复制代码

  1. function add(c, d) {
  2. return this.a + this.b + c + d;
  3. }
  4. var o = {a: 1, b: 3};
  5. add.call(o, 5, 7); // 16
  6. add.apply(o, [10, 20]); // 34
  7. // 常用的例子
  8. function bar() {
  9. console.log(Object.prototype.toString.call(this));
  10. }
  11. bar.call(7); // [object Number]
  12. bar.call("foo"); // [object String]
通过 bind 方法来绑定this

</>复制代码

  1. function fn() {
  2. return this.a;
  3. }
  4. let k = fn.bind(null);
  5. k(); // undefined
  6. //此时this === window
  7. let g = fn.bind({a: 1});
  8. g(); // 1
  9. let m = fn.bind({a: 2});
  10. m(); // 2
  11. let h = g.bind({a: 3}); // bind只会绑定一次
  12. h(); // 1
  13. // 正常返回值
  14. let obj = {
  15. a: 1,
  16. say: (function() {
  17. let _say = function() {
  18. console.log(this.a);
  19. }
  20. return _say;
  21. })()
  22. }
  23. obj.say(); // 1
  24. // bind obj
  25. var obj = {
  26. say: (function() {
  27. let _say = function() {
  28. console.log(this === window);
  29. }
  30. return _say.bind(obj);
  31. })()
  32. }
  33. obj.say(); // true
  34. // bind的简单实现
  35. Function.prototype.myBind = function(context){
  36. self = this; //保存this,即调用bind方法的目标函数
  37. return function(){
  38. return self.apply(context,arguments);
  39. };
  40. };
  41. let g1 = fn.myBind({a: 1})
  42. g1(); // 1
  43. let h1 = g1.myBind({a: 3})
  44. h1(); // 报错,
原理

</>复制代码

  1. this指的是函数运行时所在的环境,执行上下文
JavaScript 将对象存储在内存中,会将存储的地址赋给我们所申明的变量;

</>复制代码

  1. var o = {a: 5};
  2. //内存中会这样存储 o => a => {
  3. // foo: {
  4. // [[value]]: 5
  5. // [[writable]]: true
  6. // [[enumerable]]: true
  7. // [[configurable]]: true
  8. // }
  9. //}
  10. var f = function () {}
  11. var m = {a: f}
  12. // 当a的值是一个函数的时候,就会变成以下形式:
  13. //内存中会这样存储 o => a => {
  14. // foo: {
  15. // [[value]]: f的地址
  16. // [[writable]]: true
  17. // [[enumerable]]: true
  18. // [[configurable]]: true
  19. // }
  20. //}
this的作用

</>复制代码

  1. 由上面可以看出,由于函数多带带存储,可以多带带运行,运行在不同的上下文中。但要有一个机制来表示它,this就是这个作用,能够指向当前函数的运行环境;
箭头函数原理的思考

</>复制代码

  1. 箭头函数又和上文说的内容不相符。其实仔细想想,它是个语法糖,等同于给函数运用了bind方法,绑定函数的父作用域执行环境

</>复制代码

  1. let str = "windows"
  2. let o = {
  3. str: "o",
  4. methods: {
  5. str: "methods",
  6. fn: function () { console.log(this.str) },
  7. arrowFn: () => { console.log(this.str) }
  8. }
  9. }
  10. let str = "windows"
  11. let o = {
  12. str: "o",
  13. methods: {
  14. str: "methods",
  15. fn: function () { console.log(this.str) },
  16. arrowFn: function() {
  17. let fn = () => { console.log(this.str) }
  18. return fn;
  19. }
  20. }
  21. }
  22. o.methods.fn(); // methods
  23. 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元查看
<