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; }
思考
为什么要分为表达式和语句?
函数式编程倡导的无副作用与表达式之间的关系在哪?
谢谢!
js表达式和语句趣味题讲解与技术分享的更多相关文章
- js 表达式与语句
引子:表达式和语句很基础,但是有时会犯错,比如: function(){}//报错 (function(){})//不报错 function f(x){ return x + 1 }()//报错 fu ...
- js表达式和语句
表达式 一个表达式可以产生一个值,有可能是运算.函数调用.有可能是字面量.表达式可以放在任何需要值的地方. 语句 语句可以理解为一个行为,循环语句和判断语句就是典型的语句.一个程序有很多个语句组成,一 ...
- js表达式与语句的区别
http://www.2ality.com/2012/09/expressions-vs-statements.html http://www.jb51.net/article/31298.htm 表 ...
- 【.net 深呼吸】细说CodeDom(2):表达式、语句
在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...
- C Primer Plus_第5章_运算符、表达式和语句_编程练习
Practice 1. 输入分钟输出对应的小时和分钟. #include #define MIN_PER_H 60 int main(void) { int mins, hours, minutes; ...
- 算法训练 Hankson的趣味题
算法训练 Hankson的趣味题 时间限制:1.0s 内存限制:64.0MB 问题描述 Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫Han ...
- js中退出语句break,continue和return 比较
js中退出语句break,continue和return 比较 在 break,continue和return 三个关键字中, break,continue是一起的,return 是函数返回语句,但是 ...
- 1172 Hankson 的趣味题[数论]
1172 Hankson 的趣味题 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Descrip ...
- 1172 Hankson 的趣味题
1172 Hankson 的趣味题 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Descrip ...
随机推荐
- 安装ubuntu16虚拟机,下载android源码,配置编译环境
Android 源码编译步骤: 我考虑了一下,目前电脑装了SSD,8G内存,使用虚拟机编译源码应该够用. 首先下载虚拟机软件,由于最近一直在使用virtualbox,感觉蛮不错了,下载地址: http ...
- 求和:fft,表达式化简
$f(n)=\sum\limits_{i=0}^{n} \sum\limits_{j=0}^{i} S(i,j) \times 2^j \times j!$ 其中$S(i,j)$为第二类斯特林数,公式 ...
- 关于发送邮件,错误“命令顺序不正确。 服务器响应为:Error: need EHLO and AUTH first !”问题
最近做了一个小程序,通过QQ邮箱服务器发送邮件, 代码写完后,运行调试,出现“命令顺序不正确. 服务器响应为:Error: need EHLO and AUTH first !”的问题, 上网查询发现 ...
- go中的数据结构切片-slice
1.部分基本类型 go中的类型与c的相似,常用类型有一个特例:byte类型,即字节类型,长度为,默认值是0: bytes = []btye{'h', 'e', 'l', 'l', 'o'} 变量byt ...
- Master原理
1.主备切换机制原理剖析与源码分析 2.注册机制原理剖析与源码分析 3.状态改变处理机制源码分析 4.资源调度机制源码分析(schedule(),两种资源调度算法)(核心) 一.主备切换机制原理 1. ...
- linux 修改IP地址(设置为静态ip)和主机名
主机名: server0.example.com ip地址: 172.25.0.11 网络掩码: 255.255.255.0 默认网关: 172.25.0.254 域名服务器:172.25.254.2 ...
- python学习基础—day01
一. python是什么? 优势:简单, 可以跨平台 劣势:执行效率没有C语言那么高 python是解释型语言,逐行编译解释,在不同的系统windows与Linux,需要不同的解释器来编译. 而编译型 ...
- 领扣(LeetCode)翻转二叉树 个人题解
翻转一棵二叉树. 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 备注:这个问题是受到 Max Howell的 原问题 ...
- 阿里云ECS服务器部署HADOOP集群(三):ZooKeeper 完全分布式集群搭建
本篇将在阿里云ECS服务器部署HADOOP集群(一):Hadoop完全分布式集群环境搭建的基础上搭建,多添加了一个 datanode 节点 . 1 节点环境介绍: 1.1 环境介绍: 服务器:三台阿里 ...
- arm下dlsym返回的符号地址居然不是偶对齐的。
我们都知道在写汇编函数过程都会偶对齐,而gcc编译器都会将函数编译为cpu字长对齐的地址.arm指令集是固定32位指令长度,thumb指令集是固定16位指令长度, 但是运行在arm下的程序,dlsym ...