第一节: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

function fun(){}
typeof fun // "function"

var fun2=function(){}
typeof fun2 // "function"

关于通过class关键字定义的类,通过typoef计算返回的值也是function 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).  typeof运算符对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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2022-07-05 16:41  Yaopengfei  阅读(174)  评论(2编辑  收藏  举报