前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【前端】:变量提升、this绑定、 优先级与关联性

【前端】:变量提升、this绑定、 优先级与关联性

作者头像
WEBJ2EE
发布2020-02-26 09:51:55
4400
发布2020-02-26 09:51:55
举报
文章被收录于专栏:WebJ2EEWebJ2EEWebJ2EE
目录
1. 变量提升(Hoisting)
2. this 绑定
    2.1. this 是什么?
    2.2. this 绑定规则
3. 运算符优先级与关联性    
4. 几道笔试题

1. 变量提升(Hoisting)

Conceptually, for example, a strict definition of hoisting suggests that variable and function declarations are physically moved to the top of your code, but this is not in fact what happens. Instead, the variable and function declarations are put into memory during the compile phase, but stay exactly where you typed them in your code.

  • JS 引擎在执行代码之前会对代码进行编译,这一阶段会优先处理包括变量、函数在内的所有声明(提升就发生在这个时候)。
  • JavaScript 仅提升声明,而不提升初始化。如果你先使用的变量,再声明并初始化它,变量的值将是 undefined。
  • 函数声明与变量声明都会被提升。函数会首先被提升,然后才是变量;
    • 注意:对于函数来说,只有函数声明会被提升到顶部,而函数表达式不会被提升。
  • 每个作用域都会进行提升操作。

示例1:

示例2:

示例3:

示例4:

2. this 绑定

2.1. this 是什么?

  • this 提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将 API 设计得更加简洁并且易于复用。
  • this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用

2.2. this 绑定规则

  1. 由 new 调用?绑定到新创建的对象。(例如:new foo()
  1. 由 call 或 apply(或 bind)调用?绑定到指定的对象。(例如:foo.call(obj2)
    1. 注意:如果把 null 或 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。
  1. 由上下文对象调用?绑定到那个上下文对象;(例如:x.y.z.foo()
  1. 默认:在严格模式下绑定到 undefined,否则绑定到全局对象 window;(例如:foo()
  1. 箭头函数不适用上述四条规则,它会继承外层函数调用的 this 绑定。

示例1:

示例2:

示例3:

示例4:

示例5:

3. 运算符优先级与关联性

3.1. 优先级是什么?

运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。

下面从语法分析

角度理解一波优先级

优先级的产生源自于操作数不知道属于哪个操作符。以下面的表达式为例,其中大写字母是操作符,小写字母是操作数。

a B c D e

问题来了,c 是和 a 一起执行 B 操作即 (a B c)D e,还是 c 和 e 一起执行 D 操作即 a B (c D e)?中间的 c 表示很为难。运算符是由“操作符和操作数”组成的,操作符在位置上紧挨着操作数,因此对于优先级的直观理解就是,对于同一个操作数,它周围的哪个操作数更加“吸引”它,它就先跟那个操作符“优先”计算,这就是操作符优先级的由来。

当一个操作数的两边都有操作符时才是操作符绑定权限发挥作用的地方,即操作符数 c 是跟操作符 B 操作还是跟操作符 D 操作,取决于操作符 B 和 D 的优先级,谁大就跟谁。

3.1. 关联性是什么?

关联性决定了拥有相同优先级的运算符的执行顺序。考虑下面这个表达式:

a OP b OP c

左关联(左到右)相当于把左边的子表达式加上小括号(a OP b) OP c,右关联(右到左)相当于a OP (b OP c)。赋值运算符是右关联的,所以你可以这么写:

a = b = 5;

结果 a 和 b 的值都会成为5。这是因为赋值运算符的返回结果就是赋值运算符右边的那个值,具体过程是:b被赋值为5,然后a也被赋值为 b=5 的返回值,也就是5。

示例1:

示例2:

示例3:

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <script type="text/javascript">
    function Foo(){
      this.getName = function(){
        console.log(3);
        return {
          getName: getName
        }
      }
      
      getName = function(){
        console.log(1);
      };
      
      return this;
    }

    Foo.getName = function(){
      console.log(2);
    }

    Foo.prototype.getName = function(){
      console.log(2);
    }

    var getName = function(){
      console.log(4);
    }

    function getName(){
      console.log(5);
    }

    // 给出下面代码的运行结果
    Foo.getName();
    getName();
    Foo().getName();
    getName();
    new Foo.getName();
    new Foo().getName();
    new Foo().getName().getName();
    new new Foo().getName();
</script>
</body>
</html>

4. 几道笔试题

题目01:

题目02:

正确答案:A

题目03:

题目04:

参考:

《你不知道的 JavaScript(上卷)》 《自制编程语言》 运算符优先级: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence Hoisting: https://developer.mozilla.org/zh-CN/docs/Glossary/Hoisting Gentle Explanation of "this" in JavaScript: https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/ ECMA-262-10th: https://www.ecma-international.org/ecma-262/10.0/index.html#sec-this-keyword https://www.ecma-international.org/ecma-262/10.0/index.html#sec-resolvethisbinding https://www.ecma-international.org/ecma-262/10.0/index.html#sec-getthisenvironment

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档