都2020了,还不懂js运算符优先级?

5,971 阅读5分钟

题记

如果你能快速准确的回答以下问题,那么可以直接跳过

先祭出大杀招: 括点油调一成做衣 叫等位裸跳服展昭

断句:括点油,调一成,做衣; 叫等位,裸跳,服展昭

大家可以想象这样一个场景来辅助记忆:有一个服装店的老板叫展昭,我们要去他家做衣服,于是括了点油,讲价到一折,展昭很不爽,叫我们等位,不相等怎么办,表演一个裸跳(因为我们的衣服还没做好,现在是没穿衣服的哟)来说服展昭

解释

括: 括号

点: 成员访问

油:new

调:函数调用

一:一元运算符

成:乘除加减

做衣: 按位左右移

叫:比较运算符(大于 小于)

等:等于

位:按位与或

裸:逻辑与或

跳:条件运算符

服:赋值

展:展开运算符

昭:逗号

1. r等于什么

function F() {
  this.a = 1
  this.f = function() {
    this.a = 3
  }
}

F.f = function() {
  this.a = 2
}

var r = new F.f()

  • A. {a: 2}
  • B. {a: 1, f: ƒ}
  • C. {a: 3}
答案

答案: A

先执行F.f, 再执行new ...()

2. str等于什么

var str = "Hello" + true ? "World" : "JS";
  • A. "World"
  • B. "Hello World"
  • C. "Hello JS"
答案

答案: A

+的优先级高于 ...?...:...

3. a等于什么

function myFunc () {
    var x = 0;
    var y = 1
    return (x,y);
}

var a = myFunc ()
  • A. (0,1)
  • B. 0
  • C. 1
  • D. [0, 1]
答案

答案: C

逗号操作符 对它的每个操作数求值(从左到右),并返回最后一个操作数的值。

4. 打印什么

var obj = {
    a: {
        f: function(){
            return function(config){
				console.log(this)
            };
        }
    }
};
var type = "a";
var config = {};
new obj[type].f()(config);

  • A. obj
  • B. a
  • C. f
  • D. Window
答案

答案: D

js引擎将把代码解析成(new provider[type].get())(config); 因为(new provider[type].get())返回的是匿名函数,且在Window环境中执行,所以this指向Window

5.输出什么

var x = 1
console.log(x)
console.log(x++)
console.log(++x)
  • A. 1 2 3
  • B. 1 1 3
  • C. 1 1 1
  • D. 1 2 2
答案

答案: B

x++是先使用x再加1,++x是先加1再用x

6. 输出什么

var x = 1
console.log(x+++1)
console.log(++x+1)
  • A. 2 4
  • B. 3 4
  • C. 1 2
答案

答案: A

x++是先使用x再加1,++x是先加1再用x

7. 输出什么

var x = 1
console.log(!x++)

var x = 1
console.log(!++x)
  • A. false false
  • B. false true
  • C. true false
  • D. true true
答案

答案: A

第一个console, x++的优先级高于!, 所以相当于!1 等于false

第二个console, !和++x属于同一级,从右往左计算,相当于!2 等于false

8. z等于几

var x = 1
var y = 10
var z = y+++x
  • A. 11
  • B. 12
  • C. 10
  • D. 1
答案

答案: A

相当于(y++)+x

9. 输出什么

console.log(void 1 + 1)
  • A. NaN
  • B. undefined
  • C. null
  • D. 2
答案

答案: A

void的优先级高于+,所以相当于(void 1) + 1, 而void 1等于undefined,所以结果是NaN

10. 输出什么

var x = 2
console.log(x*2**3)
  • A. 16
  • B. 64
  • C. NaN
  • D. TypeError
答案

答案: A

** 优先级高于 * 相当于x * (2 ** 3)

11. 输出什么

var x = 8
console.log(x>>2+1)
  • A. 3
  • B. 1
  • C. 33
  • D. NaN
答案

答案: B

  • 优先级高于>> 相当于x >>3

12. 输出什么

var x = 8
console.log(x+=x>>2)
  • A. 4
  • B. 10
  • C. 8
  • D. 16
答案

答案: B

>优先级高于+= 相当于x += 2

13. 执行步骤是怎样

0||!0&&1

  • A. 0||(!(0&&1))
  • B. 0||((!0)&&1)
  • C. (0||(!0))&&1
答案

答案: B

! 优先级最高,先求!0

&&优先级比||高

14. 输出什么

var o ={
	ab: 1
}
console.log('a' + 'b' in o)
  • A. true
  • B. 'afalse'
  • C. 'atrue'
  • D. false
答案

答案: A

先算'a' + 'b'

15. 输出什么

function * f() {
  var x = 1
  var y = yield x + 1
  console.log(y)
  var z = yield y + 1 
  console.log(z)
}

var g = f()
console.log(g.next(10).value)
console.log(g.next(100).value)
console.log(g.next(1000).value)
  • A. 2 100 101 1000 undefined
  • B. 2 2 3 3 undefined
  • C. 2 10 11 100 1000
  • D. 2 10 11 100 undefined
答案

答案: A

Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是上一章介绍的遍历器对象(Iterator Object)。

下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。

next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值

所以console.log(g.next(10).value)的10并没有用

16. 输出什么

function f() {
    let x = y = 1
}
f()
console.log(x, y)
  • A. 1 1
  • B. undefined 1
  • C. undefined undefined
  • D. 1 undefined
答案

答案: B

赋值运算符顺序是从右到左,所以先执行y=1,由于没有定义y,所以这里y是全局变量

再把y赋值给x,但x是局部变量,在函数外访问不到

故答案是undefined 1

17. 输出什么

const colorConfig = {
  red: true,
  blue: false,
  green: true,
  black: true,
  yellow: false,
}

const colors = ["pink", "red", "blue"]

console.log(colorConfig.colors[1])

  • A. true
  • B. false
  • C. undefined
  • D. TypeError
答案

答案: D

从左往右

18. 输出什么

const str = "hello";
console.log(!typeof str === "object");
console.log(!typeof str === "string");


  • A. false true
  • B. false false
  • C. true true
  • D. true false
答案

答案: B

typeof str 返回 "string"。因此 !typeof name 返回一个布尔值 false。

false === "object" 和 false === "string" 都返回 false。

19. 输出什么

var a = {n: 1};
var b = a;
a.x = a = {n: 2};

console.log(a.x) 	
console.log(b.x)

答案

答案:

undefined

{n:2}

a.x = a = {n: 2}会先执行a.x,这里的a就是{n: 1},所以b===a此时变成了{n: 1,x:undefined} 之后从右往左执行a变成了{n: 2}, b变成了{n:1,x:{n:2}}

最终a= {n: 2}, b={n:1,x:{n:2}}

优先级汇总表

回忆一下记忆秘诀: 括点油调一成做衣 叫等位裸跳服展昭

解释

括: 括号

点: 成员访问

油:new

调:函数调用

一:一元运算符

成:乘除加减

做衣: 按位左右移

叫:比较运算符(大于 小于)

等:等于

位:按位与或

裸:逻辑与或

跳:条件运算符

服:赋值

展:展开运算符

昭:逗号

参考

个人博客

github.com/abc-club/fr…