js表达式和语句趣味题讲解与技术分享

技术分享


问题1

{ a: 1 } + 1
// ?

({ a: 1 }) + 1
// ?

1 + { a: 1 }
// ?

答案

{ a: 1 } + 1
// 1


({ a: 1 }) + 1
// "[object Object]1"


1 + { a: 1 }
// "1[object Object]"

问题2

{ 1 + 1 } + '2'
// ?

({ 1 + 1 }) + '2'
// ?

'2' + { 1 + 1 }
// ?

答案

{ 1 + 1 } + '2'
// 2 (number)


({ 1 + 1 }) + '2'
// Uncaught SyntaxError: ...


'2' + { 1 + 1 }
// Uncaught SyntaxError: ...

问题3

function foo () {
  console.log('foo expression run! index: 1')
}

var fooAlias = function foo(again) {
  console.log('named function run! index: 2')
  if (again) {
    foo()
  }
};

console.log(fooAlias.name); // ?
foo(true); // ?
fooAlias(true); // ?

答案

function foo () {
  console.log('foo expression run! index: 1')
}

var fooAlias = function foo(again) {
  console.log('named function run! index: 2')
  if (again) {
    foo()
  }
};

console.log(fooAlias.name); // chrome: foo , ie: undefined
foo(true); // foo expression run! index: 1
fooAlias(true); // named function run! index: 2
                // named function run! index: 2

表达式和语句

expression & statement

var a = 1 + 1; // 怎么区分表达式和语句?

1 + 1          // 算术表达式,返回一个值,(非表达式语句的表达式没有副作用)

var a;         // 声明语句,引起变化,产生副作用,使某件事发生

a = 1          // 赋值表达式,表达式语句

表达式

1.原始表达式

3
false
this

2.初始化表达式

{a: 1} // 容易和block混淆
[2,3]

表达式

3.函数定义表达式

var f = function f() {} // 注意这里有个等号,同时函数不是匿名的。

4.对象创建表达式

new Object()

表达式

5.属性访问表达式

obj.a

6.调用表达式

f()

7.表达式计算

eval() // 用来把参数字符串当源代码执行,并计算出一个值

表达式

8.使用运算符的表达式
(算术/比较/逻辑/赋值…表达式)

1 + 1
1 < 3
true && false
a = 1
typeof a
delete obj.a
...

语句

使某件事发生?  
1.计算带有副作用的表达式(表达式语句)  
2.声明新变量/函数(声明语句)  
3.改变语句的默认执行顺序(条件控制,循环,跳转语句,复合/块语句)  
a++                   // 计算带有副作用的表达式
var a;                // 声明新函数
function b() {}       // 声明新函数, 重点,与函数定义表达式混淆
if ()  else ()        // 改变语句的默认执行顺序
while ()              // 改变语句的默认执行顺序
{...}                 // 复合/块语句 重点!与对象字面量易混淆

在这里插入图片描述


回顾问题1

{ a: 1 } + 1 // 1

({ a: 1 }) + 1 // "[object Object]1"

1 + { a: 1 } // "1[object Object]"

回顾问题2

{ 1 + 1 } + '2' // 2 (number)

({ 1 + 1 }) + 1 // Uncaught SyntaxError: ...

'2' + { 1 + 1 } // Uncaught SyntaxError: ...

回顾问题3

function foo () {
  console.log('foo expression run! index: 1')
}

var fooAlias = function foo(again) {
  console.log('named function run! index: 2')
  if (again) {
    foo()
  }
};

console.log(fooAlias.name); // chrome: foo , ie: undefined
foo(true); // foo expression run! index: 1
fooAlias(true); // named function run! index: 2
                // named function run! index: 2

https://www.cnblogs.com/TomXu/archive/2011/12/29/2290308.html


更多:

[1,2].map(function a (item) {
  return item + 1
})
// a 未定义
// -------------------------------------

console.log(foo);
if (true) {
  function foo() { console.log('foo run') }
}
// ie function foo...  其他 undefined
// ie会当作函数定义语句,其他浏览器会提升foo变量,并将函数声明放到if语句顶部执行。
// 函数声明只能出现在所嵌套函数或全局作用域的顶部,不应该出现在其他语句中。
// 否则出现兼容性问题。

立即执行函数表达式(IIFE – Immediately-invoked function expression)

// 先用表达式和语句的知识来理解一下立即执行函数
function a () {}     // 函数声明语句

(function a () {})   // 括号用于改变运算顺序,这是一个返回函数的表达式

(function a () {})() // 返回的函数立即执行,并返回执行结果

(function a () {}()) // 返回函数执行后结果
// 除了第一句,其他几句运行后,a都是undefined,ie8以下会给a定义并提升

括号开头要小心

let f = (function () {}())
(function () {}())
// Uncaught TypeError: (intermediate value)(...) is not a function

let f = (function () {}());
(function () {}())

https://segmentfault.com/a/1190000004548664


思考

eval("{foo: 123}");     // 123

eval("({foo: 123})");   // { foo: 123 }

'use strict' // 语句还是表达式


问题4

var a
(function a() {
  return function (p) {
    console.log(eval('if (true) { { 1 + 1 } + "5" + p }'))
  }
}(3))
  (function a() {
    console.log('4')
    return 4
  }())
console.log(a)

A 4                 9                 undefined

B 4                 9                 function a() {...}

C 8                 4                 function a() {...}

D 8                 4                 undefined

答案

var a
(function a() {
  return function (p) {
    console.log(eval('if (true) { { 1 + 1 } + "5" + p }'))
  }
}(3))
  (function a() {
    console.log('4')
    return 4
  }())
console.log(a)

// 执行结果 
// 现代bro A 4 9 undefined
// ie8以下 B 4 9 function a() { console.log('4'); return 4; }

思考

  • 为什么要分为表达式和语句?

  • 函数式编程倡导的无副作用与表达式之间的关系在哪?


谢谢!

posted @ 2018-12-19 20:44  拿饭盒当烟灰缸  阅读(265)  评论(0编辑  收藏  举报