第一节:JS基础题(数据类型、字符串算法、运算符、判空等)
一. 数据类型
1. js的数据类型包括哪些?
(1). 基本数据类型:Null、Undefined、String、Boolean、Number、Symbol (6个)
(2). 引用数据类型:Object、Function、Array、Date (4个)
2. 基本数据类型和引用类型的区别?
(记忆:站队【栈-堆】)
(1). 基本数据类型存放在栈中;引用数据类型存放在堆中,在栈中存放的是地址。
(2). 基本数据类型占用空间小,大小固定;引用数据类型占用空间大,大小不固定。
3. 哪些场景中会出现undefined?【4个】
(补充:Undefined类型只有唯一的字面量值 undefined,表示变量不存在)
(1). 使用了 只声明而没有初始化的变量的,会返回undefined。
var a
console.log(a) //undefined
(2). 使用了 对象中不存在的属性的时候,会返回undefined。
var obj={
userName:'zhangsan'
}
console.log(obj.age)//undefined
(3). 函数没有返回值,却要打印函数结果,会输出undefined。
function fn(){}
console.log(fn()) //undefined
(4). 函数有多个形参,传递的参数多于函数本身的形参个数,则未匹配上的参数,会返回undefined。
function fn(p1,p2,p3){
console.log(p3) //undefined
}
fn(1,2)
4. 哪些场景中会出现null?【3个】
(补充:Null类型只有唯一的字面量值 null,表示一个空指针对象,这也就是用typeof检测null值的时候会返回object类型的原因)
(1). 一般声明一个变量,后面是为了保存某个值,可以赋值为null。
var obj=null
function foo(){
return {
userName:'zhangsan'
}
}
obj=foo();
(2). 使用js获取某个dom元素的时候,没有获取到,返回null。
document.querySelector('#id') //null
(3). 使用正则表达式match匹配的时候,没有匹配成功,返回null。
'test'.match(/a/);// null
5. Undefined和Null的 相同点 和 不同点?
相同点(4个):
(1). 二者都有且只有一个唯一的变量值,分别是 undefined 和 null
(2). 二者在转换成Boolen类型的时候,都会转换成false
(3). 二者在转换成对象的时候,都会报TypeError错误
var a;
var b=null;
cosnole.log(a.name);//Cannot read property 'name' of undefined
cosnole.log(b.name);//Cannot read property 'name' of undefined
(4). 双等运算符下 undefined== null, 返回true
不同点(4个):
(1). null在js中一个关键字,undefined在js中是一个全局变量,挂载在window下
(2). 使用typeof判断类型的时候, null返回object(空指针对象),undefined返回undefined类型
typeof undefined ;//undefined
typeof null ;//object
(3). 在进行字符串类型转换时, null转换成"null",undefined转换成"undefined"
undefined+" abc" //"undefined abc"
null+" abc" //"null abc"
(4). 在进行数值型转换是,null转换成0,可以进行计算; undefined转成NaN,不能用于计算
undefined +0;// NaN
null+0 ;// 0
建议:无论在什么情况下都没有必要将一个变量显示的赋值为undefined
。如果需要定义某个变量来保存将来要使用的对象,应该将其初始化为null
.
6. 哪些类型会转换成Boolen中的false?【6个】
false、0、NaN、undefined、“”、null, 除此之外都为true。
7. Number()、parseInt()、parseFloat() 三个函数的特殊之处?
(1).Number( )
函数转换的是传入的整个值,并不是像parseInt( )
函数和parseFloat( )
函数一样会从首位开始匹配符合条件的值。如果整个值不能被完整转换,则会返回NaN
(2). parseFloat( )
返回对应的浮点数,parseInt( )
返回整数,并且parseFloat( )
函数在解析时没有进制的概念,而parseInt()函数在解析时会依赖于出入的第二个参数来做值的转换
8. NaN是什么?
NaN是number类型中的一个特殊值,即(not a number),它表示应该返回数值而没有返回的情况, 比如0/0在js中不报错,而是返回NaN。
它有两个特点:① 任何涉及NaN的操作都返回NaN ② 与任何数值都不相等,即使他本身。
NaN==NaN //false
9. isNaN()函数和Number.isNaN()函数的区别是什么?
(1). isNaN是ES5中的函数,它的判断逻辑是 传入的内容不能转成数值的时候,返回true。
isNaN(NaN)//true
isNaN(undefined) //true
isNaN({})//true
isNaN(true)// false ,Number(true)会转换成数字1
isNaN(false)// false,Number(false)会转换成数字0
isNaN(null) // false,Number(null)会转换成数字0
isNaN(1) //false
isNaN('aaa') //true 字符串aaa无法转换成数字
isNaN('1') //false 字符串“1”可以转换成数字1.
(2). Number.isNaN是ES6中的函数,它不存在数据类型转换,直接判断传入的值是不是NaN,只有是NaN的时候,返回true。
Number.isNaN(NaN)// true
Number.isNaN(1) //false
Number.isNaN(null) //false
Number.isNaN(undefined) //false
10. String类型有哪三种创建方式?有啥区别 ?
(1). 字面量的形式:单引号和双引号效果一致。
var str='hello'
var str2="JavaScript"
(2). 直接调用String()函数: 该模式存在类型转换,默认number、boolean、null、undefined类型都会被转成字符串
String(123) // '123'
String(true)// "true"
String(null) // "null"
String(undefined) //"undefined"
(3). new String( )构造函数:该模式创建的是一个String对象实例,转换规则和上面String()函数一致
new String(678) //返回的对象中有length属性,并且可以通过下标获取对应的值。
区别:
(1). 字面量和String()创建的是字符串,比较的时候直接比较值是否相等,而new String()创建的是对象实例,比较的是栈中的地址是否相等。
var str='hello'
var str2=String('hello')
str===str2 //true
var str3=new String('hello')
var str4=new String('hello')
str3===str4 //false
二. 字符串算法
1. 字符串和数组如何相互转换?
字符串转数组:split("") 或 Array.from(xxx)
数组转字符串:join("")
{
let str = "abcdef";
// 1.1 字符串转数组
let array1 = str.split("");
let array2 = Array.from(str);
console.log(array1);
console.log(array2);
// 1.2 数组转字符串
let str2 = array1.join("");
console.log(str2);
}
2. 字符串逆序输出算法?
方案1:字符串转换成数组 split()/Array.from(xxx) → 调用reserve()方法 → 数组转换成字符串join()
{
console.log("2. 字符串逆序输出 方案1");
function reserveString(str) {
return Array.from(str).reverse().join("");
}
console.log(reserveString("abcdef"));
}
方案2:利用charAt()方法获取指定位置的字符串,索引从0开始,所以可以通过for循环遍历获取
{
console.log("2. 字符串逆序输出 方案2");
function reserveString(str) {
let result = "";
for (let i = str.length - 1; i >= 0; i--) {
result += str.charAt(i);
}
return result;
}
console.log(reserveString("abcdef"));
}
3. 统计字符串中出现最多的字符和出现次数?
方案1:先利用key-value对象存储字符串和出现次数(key为字符,value为字符出现的次数)→遍历对象→取出最多的字符和次数
{
console.log("3. 统计一个字符串出现最多的字符的个数 方案1");
function getMaxStrAndCount(str) {
let obj = {};
// 1. 遍历存储字符和出现的次数
for (let i = 0; i < str.length; i++) {
const el = str[i];
if (!obj[el]) {
obj[el] = 1;
} else {
obj[el]++;
}
}
// 2. 遍历获取出现次数最多字符和个数
let maxStr = null;
let maxCount = 0;
for (const key in obj) {
if (obj[key] > maxCount) {
maxStr = key;
maxCount = obj[key];
}
}
return `出现次数最多的字符为:${maxStr},次数为:${maxCount}`;
}
console.log(getMaxStrAndCount("aabcdbefbbbeefff"));
}
方案2:lastIndexOf()
{
console.log("3. 统计一个字符串出现最多的字符的个数 方案2");
function getMaxCount(str) {
//定义两个变量,分别表示出现最大次数和对应的字符。
var maxCount = 0,
maxCountChar = "";
//处理成数组,调用sort()函数排序,再处理成字符串
str = str.split("").sort().join("");
for (var i = 0, j = str.length; i < j; i++) {
var char = str[i];
//计算每个字符出现的次数
var charCount = str.lastIndexOf(char) - i + 1;
//与次数最大值进行比较
if (charCount > maxCount) {
//更新maxCount与maxCountChar的值
maxCount = charCount;
maxCountChar = char;
}
//变更索引为字符出现的最后位置
i = str.lastIndexOf(char);
}
return `出现次数最多的字符为:${maxCountChar},次数为:${maxCount}`;
}
console.log(getMaxCount("aabcdbefbbbeefff"));
}
4. 去除字符串中重复的字符?
方案1:利用Set结构天然去重的特点来实现,字符串转数组→传入Set中→Set转数组→数组转字符串
PS:
字符串转数组写法 : split() 或 Array.from()
Set转数组:[...mySet] 或 Array.from()
{
console.log("4. 字符串去重 方案1");
function removeStrSame1(str) {
let mySet = new Set(str.split(""));
return [...mySet].join("");
}
function removeStrSame2(str) {
let mySet = new Set(Array.from(str));
return Array.from(mySet).join("");
}
console.log(removeStrSame1("aabbaccde"));
console.log(removeStrSame2("aabbaccde"));
}
方案2:利用一个key-value对象obj,遍历字符串,字符串的值作为对象的key,value值设为true,然后判断obj中是有这个key,没有则存放到数组中,最后再将数组转成字符串即可。
{
console.log("4. 字符串去重 方案2");
function removeStrSame1(str) {
let obj = {};
let array = [];
for (let i = 0; i < str.length; i++) {
let char = str[i];
if (!obj[char]) {
obj[char] = true; //这里是精髓,便于上面if判断
array.push(char);
}
}
return array.join("");
}
console.log(removeStrSame1("aabbaccde"));
}
5. 判断一个字符串是否为回文字符串?
什么是回文字符串?一个字符串正序和倒序的值相同。
方案1:先将字符串全部转小写(不区分大小写) → 转换成数组 → 倒序 → 转换成新字符串 → 新旧字符串直接比较即可。
{
console.log("5. 判断一个字符串是否为回文字符串 方案1");
function isEequStr(str) {
let lowerStr = str.toLowerCase();
// 倒序
let dxStr = lowerStr.split("").reverse().join("");
return lowerStr === dxStr;
}
console.log(isEequStr("abcba")); //true
console.log(isEequStr("abcdef")); //false
}
方案2:先将字符串全部转小写→转成数组→while循环→从前往后的字符和从后往前的字符依次比较→只要不相等,返回false,反之while结束,返回true。
{
console.log("5. 判断一个字符串是否为回文字符串 方案2");
function isEequStr(str) {
let lowerStr = str.toLowerCase();
let strArray = lowerStr.split("");
let start = 0;
let end = strArray.length - 1;
while (start < end) {
if (strArray[start] != strArray[end]) {
return false;
} else {
start++;
end--;
}
}
return true;
}
console.log(isEequStr("abcba")); //true
console.log(isEequStr("abcdef")); //false
}
三. 运算符
1. 双(==)运算符 和 三等(===)运算符的区别?
A. 双等运算符
不同类型的数据进行比较的时候存在隐式转换,
(1). 字符串和数值比较:会将字符串转换成数值后再进行比较。
(2). boolean和数值比较:会将true转成1,false转成0后再进行比较
(3). null和undefined二者是相等的,与其他任何值==比较,都返回false
1=='1' //true
'222'==222 //true
'1'==true
'2'==true //false
'0'==false //true
null==undefined //true
null==1 //false
undefined==2 //false
B. 三等运算符
(1). 不同的数据类型相比较,不存在隐式类型转换
(2). null和undefined在===下,返回false
(3). 对于引用类型,=== 比较的数据的地址是否相等
(4). 字面量字符串和new创建的字符串在 ===下返回false
1==='1' //false
undefined===null //false
var a=[]
var b=a
var c=[]
console.log(a===b) //true
console.log(a===c) //false
'hello'===String('hello') //true
'hello'===new String('hello') //false
2. 总结 typeof 对各种数据类型的返回值情况?
typeof运算符用于返回对应的数据类型,可以是基本的数据类型,也可以是引用类型。
typeof operator
typeof (operator)
(1). Undefined
undefined本身、未声明的变量、已经声明的变量但未赋值
typeof undefined //"undefined"
typeof abc //"undefined" ,未声明的变量abc,通过typeof返回的是undefined
var sum
typeof sum //"undefined" 已经声明但是没有初始化的变量
(2). Boolean
共有两个值,ture or false,无论哪个值,返回的都是boolean
var b=true
typeof b //"boolean"
(3). Number
对于Number
类型的数,typeof
运算符在处理时会返回number
typeof 666 // "number"
typeof 66.66 // "number"
(4). String
typeof
返回的是string
typeof 'aaa' // "string"
typeof '' // "string"
(5). Function
typeof
返回的值
function fun(){}
typeof fun // "function"
var fun2=function(){}
typeof fun2 // "function"
class
关键字定义的类,通过typoef
计算返回的值也是class
是在ES6
中新增的一个关键字,原理依旧是原型继承,也就是说本质上仍然是一个Function
class Obj{
}
typeof Obj // "function"
(6). Object
对于字面量对象、数组 都返回“object”
var obj={userName:'zhangsan'}
typeof obj //"object"
var arr=[1,2,3]
typeof arr // "object"
var arr2=new Array()
typeof arr2 //"object"
(7). 运算符对null
typeof null //object
四. 常见的判空方法
1. 如何判断变量是否为空?
if(!a){ }
此时变量存在6种情况:undefined、0、NaN、false、“”、null
2. 如何判断变量为空对象{}?
思路:遍历对象的属性,如果这个属性是该对象对象本身的属性,则不是空对象,注意:如果是该对象原型链继承过来的属性,不算的。所以这里采用 hasOwnProperty()判断
{
console.log("3. 判断一个对象是否为空对象");
function isEmptyObj(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
// 测试
let obj1 = {};
let obj2 = { name: "111" };
function Person1() {
this.name = "ypf";
}
let p1 = new Person1();
function Person2() {}
Person2.prototype.name = "ypf";
let p2 = new Person2();
console.log(isEmptyObj(obj1)); //true
console.log(isEmptyObj(obj2)); //false
console.log(isEmptyObj(p1)); //false
console.log(isEmptyObj(p2)); //true
}
3. 如何判断变量为空数组?
(1). 该变量需要是一个数组 (2). 数组的length为 0.
PS:instanceof方法可以用来判断变量是否是某个对象的实例
{
let a = [];
console.log(a instanceof Array && a.length == 0);
}
4. 如何判断变量为空字符串?
方案1:直接和空字符串“”比较即可。
方案2:字符串trim()去空格后,然后length==0.
{
let str = "";
// 方案1:
console.log(str === "");
// 方案2:
console.log(str.trim().length === 0);
}
5. 如何判断变量为0 或 NaN?
任何涉及NaN的操作都为false,这里采用取非的方式进行判断。
{
console.log("4. 判断一个Number类型的变量是否是0或者NaN");
function isZeroOrNaN(num) {
return !(Number(num) && num) == true;
}
// 测试
console.log(isZeroOrNaN(0)); //true
console.log(isZeroOrNaN(NaN)); //true
console.log(isZeroOrNaN(1)); //false
}
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。