原生JavaScript灵魂拷问,你能答上多少(一)2

简介: 原生JavaScript灵魂拷问,你能答上多少(一)2

10.你能理清类型转换吗?


首先需要知道:在JavaScript中,只有三种类型的转换


  • 转换为Number类型: Number() / parseFloat() / parseInt()
  • 转化为String类型: String() / toString()
  • 转化为Boolean类型: Boolean()


因此遇到类型转换问题,只需要弄清楚在什么场景之下转换成那种类型即可。


转换为boolean


  • 显式:Boolean 方法可以显式将值转换为布尔类型
  • 隐式:通常在逻辑判断或者有逻辑运算符时触发(|| && !


Boolean(1)   // 显式类型转换
if (1) {}    // 逻辑判断类型触发隐式转换
!!1          // 逻辑运算符触发隐式转换
1 || 'hello' // 逻辑运算符触发隐式转换
复制代码


boolean 类型只有 truefalse 两种值。


除值 0,-0,null,NaN,undefined,或空字符串("")false 外,其余全为 true


转化为string


  • 显式:String 方法可以显式将值转换为字符串
  • 隐式:+ 运算符有一侧操作数为 string 类型时


转化为 string 类型的本质:需要转换为string的部分调用自身的toString方法


(null/undefined返回字符串格式的null和undefined)


当被转换值为对象时,相当于执行 ToPrimitive(input, 'hint String')


String([1,2,3]) // 1,2,3
String({x:1}) // [object Object]
1 + '1' // 11
1 + {} // 1[object Object]
复制代码


转化为number


  • 显式:Number 方法可以显式将值转化为数字类型


Number 的具体规则,ES5 规范中给了一个对应的结果表


类型 结果
undefined NaN
null +0
Boolean NaN
undefined 参数为true返回1;false返回+0
Number 返回与之相等的值
String 有些复杂,举例说明
Object 先执行ToPrimitive方法,在执行Number类型转换


  1. String: 空字符串返回 0,出现任何一个非有效数字字符,返回 NaN


console.log(Number("1 3")) // NaN
console.log(Number("abc")) // NaN
console.log(Number("1a")) // NaN
console.log(Number("0x11")) // 17
console.log(Number("123")) // 123
console.log(Number("-123")) // -123
console.log(Number("1.2")) // 1.2
复制代码


  • 隐式:number的隐式类型转换比较复杂,对需要隐式转换的部分执行 Number


  • 比较操作(<, >, <=, >=)
  • 按位操作(| & ^ ~)
  • 算数操作(+ - * / %) 注意:+的操作数存在字符串时,为string转换
  • 一元 +- 操作


11.== 的隐式转换规则


  1. ==: 只需要值相等,无需类型相等;null, undefined== 下互相等且自身等
  2. == 的转换规则:


被比较数B
Number String Boolean Object
比较数A
Number A == B A == ToNumber(B) A == ToNumber(B) A == ToPrimitive(B)
String ToNumber(A) == B A == B ToNumber(A) == ToNumber(B) ToPrimitive(B) == A
Boolean ToNumber(A) == B ToNumber(A) == ToNumber(B) ToNumber(A) == ToNumber(B) ToNumber(A) == ToPrimitive(B)
Object ToPrimitive(A) == B ToPrimitive(A) == B ToPrimitive(A) == ToPrimitive(B) A === B


在上面的表格中,ToNumber(A) 尝试在比较前将参数 A 转换为数字。


ToPrimitive(A) 将参数 A 转换为原始值( Primitive )。


12.1 + {}{} + 1的输出结果分别是什么?


通过上面的学习,当对象与其他元素相加时,对象会调用 toPrimitive 转化为原始值:


  1. 执行 toPrimitive,未传入 PreferredTypemethodNames[valueOf, toString]
  2. 执行 ({}).valueOf,返回对象本身 {},不是原始值
  3. 继续执行 ({}).toString(),返回 "[object Object]",返回结果为原始值,转换结束


此时 1 + {},右侧为 string 类型,将 1 进行 ToString() 转化为 "1" ,最后字符串连接,结果为 "1[object Object]"


注意{} + 1 输出的结果会和 1 + {} 一样吗?


{}JavaScript 中,不止可以作为对象定义,也可以作为代码块的定义。js 引擎会把 {} + 1 解析成1个代码块和1个+1,最终输出结果为 1


答案


1[object Object]
1
复制代码


13.[]与{}的相加的结果是多少?


[] + {}


数组是特殊的对象,需要调用 toPrimitive,转换为原始值


  • 执行 toPrimitive,未传入 PreferredTypemethodNames[valueOf, toString]
  • 执行 [].valueOf,返回数组本身
  • 执行 [].toString,返回空字符串 ''


空对象不做赘述。


答案


"[object Object]"
复制代码


[] + []


类似 1 两个空数组都执行 toPrimitive,返回两个空字符串。


答案

""
复制代码


{} + []


类似于 {} + 1{} + [] 相当于 {}; + [],一元 + 强制将 "" 隐式转换为0,最终结果为0


答案

0
复制代码


{} + {}


对于这个题,我先公布一下答案,之后说一下我的疑问。


答案


[object Object][object Object]
复制代码


疑问


为什么 JavaScript 引擎没有将前面的 {} 解释成代码块?


友情提示:由于 {} 可以解释为代码块的形式,有些需要注意的地方,举个栗子:

  • 空对象调用方法时:{}.toString() 会报错
  • 箭头函数返回对象时:let getTempItem = id => { id: id, name: "Temp" } 会报错


14.你能灵活运用 parseInt 与 parseFloat 吗


  1. parseInt:从数字类开始看,看到非数字类为止,返回原来的数。(小数点也属于非有效数字)


parseInt('123x') -> 123
parseInt('-023x') -> -23
parseInt('1.1') -> 1
parseInt('-abc') -> NaN
parseInt('x123') -> NaN
复制代码


  1. parseInt(string, radix) 还有第二个参数 radix 表示要解析数字的基数,取值为 2~36 (默认值为10)
  2. parseFloatparseInt 类似,只不过它返回浮点数。从数字类开始看,看到除了第一个点以外的非数字类为截止,返回前面的数。


网红题:['1','2','3'].map(parseInt)


这个网红题考察的就是 parseInt 有两个参数。 map 传入的函数可执行三个参数:


// ele   遍历的元素
// index 遍历的元素索引
// arr   数组
arr.map(function(ele, index, arr){})
复制代码


['1','2','3'].map(parseInt)相当于执行了以下三次过程:


parseInt('1', 0, ['1','2','3'])
parseInt('2', 1, ['1','2','3'])
parseInt('3', 2, ['1','2','3'])
复制代码


  • parseInt('1', 0, ['1','2','3']): radix为0时,默认取10,最后返回1
  • parseInt('2', 1, ['1','2','3']): radix取值为2~36,返回NaN
  • parseInt('3', 2, ['1','2','3']): radix取值为2,二进制只包括0,1,返回NaN


15.如何让 if(a == 1 && a == 2) 条件成立?


valueOf 的应用


var a = {
    value: 0,
    valueOf: function() {
        this.value++;
        return this.value;
    }
};
console.log(a == 1 && a == 2); //true


相关文章
|
17天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
27 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
2月前
|
移动开发 前端开发 JavaScript
原生JavaScript+canvas实现五子棋游戏_值得一看
本文介绍了如何使用原生JavaScript和HTML5的Canvas API实现五子棋游戏,包括棋盘的绘制、棋子的生成和落子、以及判断胜负的逻辑,提供了详细的代码和注释。
37 0
原生JavaScript+canvas实现五子棋游戏_值得一看
|
3月前
|
Devops 持续交付 测试技术
JSF遇上DevOps:开发流程将迎巨变?一篇文章带你领略高效协同的魅力!
【8月更文挑战第31天】本文探讨了如何在JavaServer Faces(JSF)开发中融入DevOps文化,通过持续集成与部署、自动化测试、监控与日志记录及反馈机制,提升软件交付速度与质量。文中详细介绍了使用Jenkins进行自动化部署、JUnit与Selenium进行自动化测试、ELK Stack进行日志监控的具体方法,并强调了持续改进的重要性。
39 0
|
3月前
|
JavaScript 前端开发 API
从零开始学表单操作,jQuery 与原生 JavaScript 完全指南,带你轻松掌握网页交互关键!
【8月更文挑战第31天】在网页开发中,表单是实现用户互动的关键元素。无论是收集信息、提交数据还是验证输入,都需要对表单进行有效操作。本文档介绍了如何使用原生 JavaScript 和 jQuery 操作表单,包括获取表单元素、读写表单值、处理表单提交及验证等核心功能。jQuery 提供了更简洁的语法和更好的兼容性,但原生 JavaScript 在性能上有优势。选择合适的方法取决于项目需求和个人偏好。下面通过具体示例展示了两种方式的操作方法。
39 0
|
5月前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
4月前
|
JavaScript
js 一键复制到剪贴板(原生js实现)
js 一键复制到剪贴板(原生js实现)
32 0
|
5月前
|
前端开发 JavaScript 容器
程序技术好文:纯原生javascript下拉框表单美化实例教程
程序技术好文:纯原生javascript下拉框表单美化实例教程
91 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
97 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
129 4
下一篇
无影云桌面