一些有意思的JavaScript代码片段
Javascript是一门很灵活的语言,我们可以使用它动态地实现各种各样的功能。但是动态带来便利的同时,也存在一些令人费解的行为,稍不注意就会进入误区一个接着一个的坑。虽然我使用JavaScript的时间还不算长,也是遇到了一些有意思的场景,一开始百思不得其解,弄清楚之后又让我哭笑不得。现在就来跟大家一起分享一下。
语法糖带来的浅拷贝
先来预测一下下面代码的输出内容:
const user = {
name: 'zong',
location: {
city: 'Shanghai',
state: 'Shanghai'
}
};
const copy = Object.assign({}, user);
// 或者
// const copy = { ...user };
copy.location.city = 'Suzhou';
console.log('original: ', user.location);
console.log('copy:', copy.location);
输出结果应该是:
original: {
city: 'Shanghai',
state: 'Shanghai'
}
copy: {
city: 'Shanghai',
state: 'Shanghai'
}
咦?为什么操作复制的对象会修改原来的对象呢?这是因为Object.assign
跟spread operator
只做了一层浅拷贝
,这意味着只有对象的第一层属性会被复制,如果某个属性是个嵌套的对象,那么只有引用会被复制,所以我们操作修改的对象的属性影响到了原来的对象。
所以在我们这个例子中copy
的location
属性将仍然指向原来user
对象对应的location
属性。
JavaScript从右向左赋值的行为
function display() {
var a = b = 10;
}
display();
console.log('b', typeof b === 'undefined');
console.log('a', typeof a === 'undefined');
输出是:
b false
a true
这是因为JavaScript赋值操作符是从右向左的,这意味着我们的赋值操作也是从右向左来的,首先b
会被赋值10
,然后它被赋给了a
。
所以:
function display() {
var a = b = 10;
}
等同于:
function display() {
b = 10;
var a = b;
}
所以b
没有用var
声明成了一个全局变量,所以在外部可以被访问到,而a
只是个局部变量,所以外部会打印出a === undefined
为true
。
但是如果上面的代码在严格模式
中执行的话,情况又不一样了,由于严格模式不允许创建全局变量所以这段代码会直接抛出异常。
提升
var num = 8;
var display = function () {
console.log(num);
var number = 20;
};
display();
猜猜这里的输出结果是什么?它不是8
而是undefined
,这又是为什么?
这是因为JavaScript里面有个现象叫提升
。提升
是JavaScript中把变量声明移到当前作用域最顶部的一种行为。
所以上面的代码可以转换成如下:
var num = 8;
var display = function () {
var num;
console.log(num);
num = 20;
};
display();
我们可以看到只有声明被移到了函数的最顶端,而赋值操作还在原地,所以这边num
由于还未赋值会打印出undefined
。
delete的作用对象
const num = 1;
const result = (function () {
delete num;
return num;
})();
console.log(result);
这边的代码不会报出任何错,因为我们是在number
类型上使用的delete
,它还是会打印出1
。
The delete
操作符被用来删除一个对象的属性,在这儿num
并不是一个对象所以它会返回这个变量对应的值,也就是1
。
const num = 1;
const result = (function (num) {
delete num;
return num;
})(10);
console.log(result);
上面的代码将输出10
。
这边我们把10
作为参数传给函数,同样地delete
在这里对原始类型也不起作用,所以会照常打印出10
。
好啦,今天的分享就到这里啦,主要是在使用JavaScript的过程中可能会经常遇到的一些细节问题,希望能给大家带来一丢丢的收获,happy coding~
- SpringCloud配置中心高可用搭建
- hadoop压缩与解压
- cordova插件- Media
- JDK8之新特性扩展篇
- Java管理Cookie增删改查操作。
- Intellij Idea乱码解决方案都在这里了
- 神奇,教你用随机数打印hello world
- Mapreduce任务实现邮件监控
- Eclipse中Maven打包程序并在Linux中运行
- SDN开发笔记(七):L2switch源码分析(上)
- spark使用zipWithIndex和zipWithUniqueId为rdd中每条数据添加索引数据
- Spring Boot Server容器配置
- Spring Boot读取配置的几种方式
- 如何用TensorFlow构建RNN?这里有一份极简的教程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 误差线怎么画,写不写代码as you like
- Nomogram(诺莫图) | Logistic、Cox生存分析结果可视化
- Forest plot(森林图) | Cox生存分析可视化
- R-forestplot包| HR结果绘制森林图
- 韦恩图
- R-plotly|交互式甘特图(Gantt chart)-项目管理/学习计划
- Python的这些高级用法你都知道吗?
- ggstatsplot绘图|统计+可视化,学术科研神器
- 用python下载哔哩哔哩视频?
- 数据处理|数据查重怎么办?去重,就这么办!
- FFmpeg合并MP4文件
- Broom |tidy up a bit,模型,检验结果一键输出!
- 今日算法题-动态规划法
- 3分钟短文 | PHP获取函数的代码片段,唯有反射最高效!
- ggforce|绘制区域轮廓-区域放大-寻找你的“onepiece”