简单的说一下JavaScript中的动态变量

简单的说一下JavaScript中的动态变量

我们从一个很简单的示例开始说起

1
2
3
4
5
6
7
8
[] + {}
// '[object Object]'
{} + []
// 0
{} + {}
// NaN
[] + []
// ''

由于时间关系,我在这片笔记中就不展开说了。简单的说一下上面几个语句。

JavaScript 中的比较

基本类型的比较

A↓\B→UndefinedNullNumberStringBooleanObject
UndefinedtruetruefalsefalsefalseIsFalsy(B)
NulltruetruefalsefalsefalseIsFalsy(B)
NumberfalsefalseA === BA === ToNumber(B)A=== ToNumber(B)A== ToPrimitive(B)
StringfalsefalseToNumber(A) === BA === BToNumber(A) === ToNumber(B)ToPrimitive(B) == A
BooleanfalsefalseToNumber(A) === BToNumber(A) === ToNumber(B)A === BToNumber(A) == ToPrimitive(B)
ObjectfalsefalseToPrimitive(A) == BToPrimitive(A) == BToPrimitive(A) == ToNumber(B)A === B

值得注意的是,由于Symbol是一个唯一值,所以一般情况下和其他的值比较,都是false,除了一种情况:

1
2
3
4
5
6
7
8
let x = Symbol('Nothing or some Strings.')
let y = new Object(x)
let z = Object(x)

x == y
// true
x == z
// true

除了上述的情况以外,下面的都是false

1
2
3
4
5
6
7
8
x === y
// false
x === z
// false
y == z
// false
y === z
// false

判等

xy=====Object.is
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
"foo""foo"truetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
""falsetruefalsefalse
""0truefalsefalse
"0"0truefalsefalse
"17"17truefalsefalse
[1,2]"1,2"truefalsefalse
new String("foo")"foo"truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
{ foo: "bar" }{ foo: "bar" }falsefalsefalse
new String("foo")new String("foo")falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
"foo"NaNfalsefalsefalse
NaNNaNfalsefalsetrue

再说回去

加法运算中,其实就是用到了上面的隐式类型转换。

  1. [],在LHS操作和RHS操作时,都会将其先拆箱(通过[].valueOf(),然后发现其不是一个原始值,会进行ToPrimitive操作,最终的到的值是:'',即空字符串)。
  2. {},在LHS操作时和RHS操作时的表现是不一样的,LHS操作的时候,{}在语义和语法上,会被当做是一个代码块。而在RHS的时候,会和[]一样,进行先valueOfToPrimitive的拆箱操作。

那么,我们来看一下第一小节提出的那几个问题。

  1. [],拆箱的话会先执行[].valueOf(),得到的是[],并不是原始值,就执行[].toString(),得到的结果是''
  2. {},拆箱会先执行{}.valueOf(),得到的是{},并不是原始值,于是执行toString(),得到的结果是[object Object]
  3. []+{}就相当于""+"[object Object]",结果就是[object Object]。
  4. {}+[]的话,js 会把开头的{}理解成代码块,如果是一个空白的代码块,JS 引擎会忽略它,相当于没有任何东西。所以这句话就相当于+[],也就是等于+"",将空字符串转换为数字类型,结果就是0
  5. {}+{}的话,也是和上面一样的道理,相当于+"[object Object]",将字符串转化为数字类型,结果是NaN
  6. []+[]就相当于""+"",所以结果还是""

参考

  1. JavaScript 对象转换到基本类型值算法 ToPrimitive

评论

Agile Angularjs Animation Application Artificial Intelligence BP Babel Bokeh Book C4.5 CART CD CLI CSS CentOS CheetSheet Cinder Clipboardjs Concept Continuous Delivery DeepLearning Department DevOps Develop Development Directive Distribution Django Document ECMA ELU ES5 ES6 ES7 Echarts Engine Entropy Filter Front End GELU Gallery Git Gradient descent Hexo Horizon ID3 ID3.5 Icarus JavaScript Javascript KVM LaTeX LeetCode LibreOffice Linux Logestic MNIST Machine Learning Mathematics Matrix MiddleWare Module Native Network Nginx NodeJS Numpy OOP OpenSSH OpenStack OpenStackApi Operations Oprations PDF PLA Pandas Pipline Probability Python ReLU React Relational algebra Restful Route SVD SVM Scalar Sigmoid SoftPlus Swish Team Tempest Tensor TensorFlow Testing Time TimeMachine Tips Vector Vmware Vue Vuex WSGI Web Word Cut aliyun auth babel certbot cost function debounce decision tree dns docker dockerfile eject error function footer git header homebrew html5 http https jupyter jwt keystone lab loader lodash loss function mathematics migrate nav openstack outline pdf2html pm2 proto prototype python replace request response rp rt ruby scikit-learn section singular value decomposition sklearn stylus tanh throttle url vue-router vue-ssr webpack 事件 事件代理 事件冒泡 事件捕获 位运算 低通滤波器 入门 全局 全局变量 全局对象 全栈 公式 决策树 几何意义 函数 分类器 剪枝 加速 动态变量 匹配滤波边缘检测 卷积 卷积核 原型链 双向绑定 反向传播 发布 变量类型 可视化 基尼指数 官方示例 对偶形式 对象 小技巧 平移和查分边缘检测 思维导图 感知机模型 手动实现 拉格朗日乘子法 推导 提交阶段 数据 数据绑定 最大似然估计 最小二乘估计 最小二乘回归树 最小二乘法 本地 朴素贝叶斯 朴素贝叶斯算法 机器学习 条件概率 标签模板 梯度下降 梯度方向边缘检测 概念 概率 模板字符 模板字符串 正则 求导 流程 源码 源码阅读 激活函数 灰度 特征值 特征向量 特征工程 生命周期 矩阵 神经元 神经网络 私有对象 科学计算 算法 算法实现 线性代数 线性回归 编译 缺失 联合概率 脚手架 识别 调试 贝叶斯 贝叶斯判定准则 边缘检测 边际概率 闭包 间隔 防抖动 限流 随机森林 高斯分布 高通滤波器
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×