js笔试题系列之——基础类型与运算符

  前端技术的发展速度大家有目共睹,js的ECMA标准也不再是3的天下,但不管再怎么山雨欲来风满楼,基础语法还是得温故而知新。无论你是初学则还是多年js的编程者,都可以试着做做下面的测试题,我相信总还是会有些收获的。因为全部是自己总结和手打的,有纰漏错误之处请留言,谢谢。

一:考察基本数据类型与运算符

(1)

var a;
console.log(typeof a); ==>undefined

  先以一个最常见也是最简单的测试案例开始,未定义的变量或者未赋值则为undefined

(2)

var a = ‘1a‘;
console.log(a++); ==>NaN

  ++操作符将对a变量隐式转换为number类型,字符串‘1a‘无法正常转换为数字,所以返回NaN。

  这里可以总结出以下几点:

  1. 除了+操作符以外,-、*、/、%、++、--都将隐式转换参与运算的变量为number类型,如果能正常转换为数字则返回该数字,否则返回NaN;

  2. 能正常转换为数字的有如下几种情况:

    纯数字类字符串如‘123‘、‘1e2‘(转换为1*10的2次方等于100);

    null参与运算转换为0(null-4等于-4,null+null等于0);

    boolean类型的true和false分别可转换为1和0;

  3. 只有能够转换为数字的变量才能参与++或--运算,否则将报错,比如:  

console.log(3++); ==>报错,常量不能直接运算++
var a = 3;
console.log(a++); ==>3

  其中有个特例:NaN++可以正常返回结果,仍然是NaN

(3)

console.log(2+‘1‘); ==>‘21‘
console.log(2-‘1‘); ==>1
console.log(1+NaN); ==>NaN
console.log(‘1‘+NaN); ==>‘1NaN‘

  1. +运算符有必要单独一提,因为除了+以外的其它算术运算符,都会对参与运算的变量或值默认隐式转换为number,但+因为在js中还肩负着字符串合并的重大任务,所以它有特殊‘国情‘:

    1.1 当+的左右两边均是数字类型时,则执行算术运算,比如1+2返回3、NaN+1返回NaN;

    1.2 当+的左右两边均是字符串类型时,则执行字符串合并,比如‘1‘+‘2‘返回‘12‘;

    1.3 当+的左右两边一个是数字、一个是字符串类型时候,则先将数字转换为字符串再合并,比如1+‘1‘返回‘11‘;

  2. 在实际开发过程中,我们使用+运算符基本上都是处理字符串类型或者数字类型的,所以上面的三种情况能够应对大部分开发场景。但是当+运算符的左右两边出现了第三种数据类型时,情况就会显得复杂了(以下其它数据类型是指除了string和number的以外类型):

    2.1 其它数据类型+字符串类型

console.log(null+‘1‘); ==>‘null1‘
console.log(undefined+‘1‘); ==>‘undefined1‘
console.log([1,2]+‘1‘); ==>‘121‘
console.log((function(){})+‘1‘); ==>‘function (){}1‘
console.log(({})+‘1‘); ==>‘[object Object]1‘

  执行办法:其它数据类型将被转换为字符串再合并,且对象类型将调用自身toString()方法转换结果。另外,其实对象类型+运算无论另外一个参与运算的值是不是字符串类型,都只能与它进行字符串合并操作,而不能是四则运算,下面会具体讲到。

    2.3 其它数据类型+数字类型

console.log(null+1); ==>1
console.log(undefined+1); ==>NaN
console.log(true+1); ==>2
console.log([1]+1); ==>‘11‘
console.log((function(){})+1); ==>‘function (){}1‘
console.log(({})+1); ==>‘[object Object]1‘

  执行办法:非对象类型将进行四则运算,而对象类型场景则仍然是字符串合并的操作。

    2.2 其它数据类型+其它数据类型

console.log(null+null); ==>0
console.log(undefined+undefined); ==>0
console.log(true+true); ==>2
console.log([1]+[2]); ==>‘12‘
console.log((function(){})+(function(){})); ==>‘function (){}function (){}‘
console.log(({})+({})); ==>‘[object Object][object Object]‘

  执行办法:非对象类型将进行四则运算,而对象类型场景则仍然是字符串合并的操作。

  所以,关于有其它类型参与+运算的场景,我们可以再稍总结下最终的结果:只要有对象类型参与+运算,则永远是做字符串合并;如果是null/undefined/boolean类型参与+运算,当另一个参与运算的值为字符串,则进行字符串合并,否则进行四则运算。

思考题:alert({name:‘mofei‘})

(4) 

console.log(1+ +1); ==>2
console.log(1e+1+1); ==>11

  这个测试仍然是+运算,但是并没有和上一个测试案例合并在一起而是单独出来,原因很简单:此+非彼+。

  +运算符实际上在js中有三种应用场景:转换为数字、四则运算加、字符串连接。在上一个测试案例中我们讲了后两种应用场景,而这里是则是对第一个应用场景的补充。关于转换为数字的理解也不难,我们经常用a+‘‘的写法将一个变量转换为字符串类型,所以我们也可以利用+运算符将其它类型转换为数值类型,比如+null返回结果为0。所以在这个案例中,1+ +1等同与1+1,因为后面那个+1其实就是将1转换为number类型,仍然是1,而1e+1+1等效于1e1+1,也就是11。

(5)

console.log(10/0); ==>Infinity
console.log(10%0); ==>NaN

  除0返回Infinity,对0取模(求除法运算的余数,对2取模常用在判断奇偶)返回NaN。

(6)

console.log(!!false); ==>false
console.log(!!4); ==>true
console.log(!!‘false‘); ==>true

  这里考察了取反运算符。双取反实际上就是将运算对象强制转换为boolean型,其中最后一个要注意‘false‘本身是个非空字符串,转换为布尔值为true。

  大部分情况下转布尔值都是返回true,除了以下几种情况:false本身、null、nudefined、空字符串‘‘、数字0、数字NaN

思考题:!!undefined

(7)

console.log(typeof(0)); ==>numberconsole.log(typeof(NaN)); ==>number
console.log(typeof(‘0‘)); ==>string
console.log(typeof(‘false‘)); ==>string
console.log(typeof(false)); ==>boolean
console.log(typeof(undefined)); ==>undefined
console.log(typeof(null)); ==>object
console.log(typeof([1,2])); ==>object
console.log(typeof(function(){})); ==>function

  这里罗列了typeof可以返回的所有可能值:number、string、boolean、undefined、object、function

  可以总结的知识点是:

  1. 凡是带上引号的typeof就是string,而不需要管里面内容是什么,比如不要误以为typeof(‘undefined‘)结果就是undefined

  2. null、数组array、普通对象的typeof返回为object

  3. 函数本身也是对象,但是它的typeof返回为特殊的function

  4. 并不能依靠typeof全部分别出变量到底属于8种数据类型中的哪一种(比如数组和普通对象),但是可以直接区分基本数据类型中的四种类型:number、string、boolean、undefined,如果要全部区分类型可以结合其它方法共同判断(如instanceof、constructor),或者使用Object.prototype.toString.call(...)

(8)

console.log(null == undefined); ==>true
console.log(false == ‘‘); ==>true
console.log(false === !true); ==>true
console.log([] === []); ==>false

  关于等于运算符==:比较双方是否相等,这种比较是允许进行类型转换的,比如1 == ‘1‘将返回true,至于它们是怎样进行类型转换可以参照《javascript权威指南》75页有非常详细的描述,这里不再阐述了。严格等运算符经常在对象的比较中被考察,我们要知道对象的比较是通过引用比较的,所以在这个测试案例中,它们虽然看上去很像,其实是两个不同的对象(这里也是数组),它们并没有引用同一个地址,所以并不严格等,对象严格等的情况如下:

var a = [];
var b = a;
console.log(a === b); ==>true

  b变量被赋值为a,a本质是对象,对象赋值为引用赋值,此时a和b公用一个地址,所以严格等成立。

  此外,关于==还有个比较经典的问题:

console.log([] == ![]); ==>true

  因为!运算符优先级原因,将先执行![],所以这里等效于 [] == false,按照常识在boolean环境下空数组是转换为true的,但是实际上在==环境中,是通过转换为数字或字符串来比较的,当操作值有boolean类型时转换为数值比较,也就是[]转换为number类型为0,false转换为number类型为0,所以结果返回true。看上去这些繁琐的转换实在令人担忧,但实际也没有这么糟糕,毕竟这种看上去“非人性”的结果在实际开发场景中极少遇到,当你有一定的经验的时候,绝大部分宽松相等的结果你还是能够一眼识破的。  

(9)

console.log(1&&2); ==>2
console.log(1||2); ==>1
console.log(1&&a=2); ==>error
console.log(1&&(a=2)); ==>2

  关于&&和||两个运算符,也是笔试中的常客。这里有几点需要注意:

  1. &&和||返回的是表达式的值,而并不是true或者false

  2. 从左到右执行,&&左侧的表达式返回值如果转换布尔型为true时,则将执行右侧的表达式;||左侧的表达式返回值如果转换布尔型为true时,则直接返回该表达式返回值且不再执行右侧表达式

  有了以上两点,前两个测试则比较容易理解了,而对于1&&a=2,实际等同于——(1&&a)=2——undefined=2,执行将报错;只要给a=2加上小括号优先执行则可以正常运行,其中a=2的返回值为2,所以最终表达式的值为2。

 

时间: 2025-01-18 14:05:36

js笔试题系列之——基础类型与运算符的相关文章

js笔试题系列之三——函数

在这一章以函数为主的讲解中,也会不可避免的牵涉到数组和对象的内容,这也不难理解,知识往后走牵涉的内容自然也越多. (1)经典作用域问题 题一: var a = 0 function f(){ console.log(a); ==>undefined var a = 2; console.log(a); ==>2 } f() 第二次日志输出结果相对容易理解,关键是第一次打印结果并不是全局变量中的a,因为按照作用域链的查找规则,在函数执行的时候会先查找局部作用域,而此时局部作用域已经存在变量a,只

js笔试题系列之二——数组

(1)快速创建一个数组,数组中含有100个值为0元素. 方法一: var arr = new Array(100); for(var i=0;i<100;i++){ arr[i] = 0; } 方法二: var arr = new Array(100); arr.join('0').split(''); //注意此方法结果0为字符类型 面试官会喜欢哪个答案呢? (2)经典的数组去重问题 数组去重可以说是各大公司前端笔试中的常见题,以下列出几种典型的解决方法 方法一:传统双循环对比法 functi

容易答错的JS笔试题

1,考察this var length = 10 function fn(){     alert(this.length) } var obj = {     length: 5,     method: function(fn) {         fn() // ?         arguments[0]() // ?     } } obj.method(fn) 这里的坑主要是arguments,我们知道取对象属于除了点操作符还可以用中括号,这里fn的scope是arguments,即

JS笔试题

1,考察this var length = 10function fn(){ alert(this.length)}var obj = { length: 5, method: function(fn) { fn() // ? arguments[0]() // ? }}obj.method(fn)这里的坑主要是arguments,我们知道取对象属于除了点操作符还可以用中括号,这里fn的scope是arguments,即fn内的this===arguments,调用时仅传了一个参数fn,因此le

笔试题系列001

测试笔试题类型:软件测试| 试题:55道试题(50道选择题,5道问答题)http://bbs.sjtu.edu.cn/bbsanc,path,%2Fgroups%2FGROUP_9%2FJobInfo%2FD7CD26755%2FD85486036%2FM.1131274669.A.html http://202.197.191.206:8080/38/text/test/test_2/shijuan2.htm 软件工程 http://test.examw.com/410/P6517/一.单选题

这道JS笔试题你做对了吗?

昨天在看一道笔试题的时候本以为很简单,但是结果不是我想象的那样,直接上笔试题. const array = new Array(5).map((item) => { return item = { name: '1' } }); console.log(array); // 请写出输出结果 我想象的答案:[{name: '1'}, {name: '1'}, {name: '1'}, {name: '1'}, {name: '1'}]; 实际的答案:[empty × 5] 为什么会这样了? 猜想1

蛮考验基础的JS笔试题(有坑小心!)

1.  考察this 1 var length = 10 2 function fn(){ 3 alert(this.length) 4 } 5 var obj = { 6 length: 5, 7 method: function(fn) { 8 fn() // ? 9 arguments[0]() // ? 10 } 11 } 12 obj.method(fn) 这里的坑主要是arguments,我们知道取对象属于除了点操作符还可以用中括号,这里fn的scope是arguments,即fn内

由几道JS笔试题引发的知识点探究十五——JS面向对象编程

JS初学者大都没有认识到其强大的面向对象编程的特性,只是把JS当作一门简单实用的脚本语言来用.也正因如此,JS程序员往往处于程序员鄙视链的最低端,很多人觉得JS是HTML一类的语言,甚至连语言都称不上.事实完全不是如此,你若也有这种想法,说明你对JS的认识太浅薄了.要想正真迈入JS的大门,你必须深入了解JS面向对象编程的特性.下面就让我为大家一一道来. 一.创建对象 既然是面向对象,那肯定先得有对象吧,要有对象,肯定得知道对象是什么吧,那JS中的对象是什么呢?在C++里我们知道,对象就是类或结构

由几道JS笔试题引发的知识点探究二——强制类型转换

强制类型转换的概念相信大家一定不陌生,例如整数和浮点数进行算术运算,整数会在后台转型为浮点数.JS作为一门弱类型的动态脚本语言,任何两种数据类型之间都可以进行性转换而不会报错,这就带来了一整套错综复杂的类型转换规则.例如我们的题目 alert('5'+5),大家都知道答案是'55',但为什么这里不将string转换成number而要将number转换成string呢?在其他情况下也都要将string转型成number吗?下面我们就来做一次完整的总结. 一.何时转型为boolean? 1. 逻辑非