JS基础面试题

一,数据类型

值类型:

  1. 数字
  2. 字符串
  3. 布尔
  4. undefined
  5. null

引用类型

  1. 数组
  2. 对象
  3. 函数
  4. set(es6新增)
  5. map(es6新增)

值类型与引用类型的区别?

  1. 值类型的key与value都存储在栈区
  2. 引用类型数据将key存储在堆区,而将真正的值存储在栈区
  3. 如果将一个引用类型的数据直接赋值给一个变量,实际上是将这个变量的地址复制给了这个变量,而并非真正的值;
二,数据类型的判断
  1. typeof
    只能判断值类型与引用类型的数据
    在这里插入图片描述

  2. instance of
    判断是否为某个数据类型的实例
    在这里插入图片描述

  3. constructor
    判断是否某个数据类型的构造者
    在这里插入图片描述

  4. isArray
    数组专用,判断是否为数组

  5. Object.prototype.toString.call()
    最为准确,可以精准具体判断是哪一个数据类型
    在这里插入图片描述
    可以为第五组判断方法封装一个函数

	<script>
		function Gettype(obj){
			return Object.prototype.toString.call(obj).slice(8,-1)
		}
	</script>

斐波拉契数列

求斐波那契 数为n的数列

1,1,2,3,5,8,13,21,34,55,89,…

function fib(n){
    if(n == 0 || n == 1){ //如果是第0位返回1,如果是第1位返回1
        return 1
    }else{
        return fib(n - 1) + fib(n - 2) //如果其他位 返回 前面两个数的和
    }
}

// alert(fib(41));此种方法计算有局限,最高计算到41位

//分析
/*
n=0时,fib(0)==>  return 1
n=1时,fib(1)==>  return 1
n=2时,fib(2)==> return  fib(1)+fib(0)==>1+1=2
n=3时,fib(3)==> return  fib(2)+fib(1)==>2+1=3
n=4时,fib(4)==> return  fib(3)+fib(2)==>3+2=5

*/

三,深浅拷贝
  • 浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用;直接将一个值赋值给一个变量就是浅拷贝
  • 深拷贝:创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”,新对象跟原对象不共享内存,修改新对象不会改到原对象
  • Es6扩展
		var obj1 = {
			name: "张三",
			age: 18,
			friend: ['小红', '小绿', {
				name: "小蓝",
				job: "teacher"
			}]
		}
				var obj2 = {
			...obj1
		}
  • for循环
		var obj3 = {};
		for (var k in obj1) {
			obj3[k] = obj1[k];
		}
  • assign
				//第三种               (目标对象,源对象)
		var obj4 = Object.assign({}, obj1)
		console.log(obj4)
  • 递归
	function deepCopy(obj1) {
			if (typeof obj1 == "object"&obj1!=null) {
				var temp = null
				if (obj1 instanceof Array) {
					temp = [];
					for (var i = 0; i < obj1.length; i++) {
						temp[i] = deepCopy(obj1[i]);
					}
				} else {
					temp = {};
						for (var k in obj1) {
							temp[k] = deepCopy(obj1[k])
						}
				}
				return temp;
			} else {
				return obj1;
			}
		}
		//浅拷贝三种方式
		var obj1 = {
			name: "张三",
			age: 18,
			friend: ['小红', '小绿', {
				name: "小蓝",
				job: "teacher"
			}]
		}
				//第一种:Es6扩展
		var obj2 = {
			...obj1
		}
				//第二种:for循环
		var obj3 = {};
		for (var k in obj1) {
			obj3[k] = obj1[k];
		}
				//第三种               (目标对象,源对象)
		var obj4 = Object.assign({}, obj1)
		console.log(obj4)
				//第四种递归
		function deepCopy(obj1) {
			if (typeof obj1 == "object"&obj1!=null) {
				var temp = null
				if (obj1 instanceof Array) {
					temp = [];
					for (var i = 0; i < obj1.length; i++) {
						temp[i] = deepCopy(obj1[i]);
					}
				} else {
					temp = {};
						for (var k in obj1) {
							temp[k] = deepCopy(obj1[k])
						}
				}
				return temp;
			} else {
				return obj1;
			}
		}
四,隐式转换
  1. 字符串与任意类型的数据链接都会转换成字符串
                var a="100" //字符串
                var b=10;  //数字
                var c = a+b; //10010 
  1. 数学运算符会尝试将隐式转换成数字;如果没有将数据转换成功,结果就是NaN
                var a="10";
                var b=2;
                var c =a*b //20;
                
                var a ="abc10"
                var b=2;
                var c =a*b // NaN;
  1. 算数运算会将布尔类型默认转换成0,1
                var a =false;
                var b=2;
                var c =a*b; //0;
  1. 空字符串,0,null,undefined NaN false会被转换成false,其他都会转换成true
                var a ="";
                var b = true;
                console.log(!!a);
等于判断

== (等于) 判断隐式转换后值是否相等
=== (严格等于) 判断类型与值是否相对

  1. ==判断
console.log(100 == "100");  //true(如果两边类似数字会优先隐式转换为数字)
console.log("" == false);  //true
console.log(1 == true);// true
console.log(null == undefined);// true 隐式转换后都为fasle
console.log(null == null);  // true  空指针都指向一个地方(空)
console.log(undefined == undefined);//
console.log(null == NaN);false(特殊) 数字不等于空
console.log([] == []);//false  //两块不同的内存地址
console.log({}== {});//false  //两块不同的内存地址

  1. ===严格等于
// === 严格等于 判断类型 与值 是否相对
alert(0 === ""); //false
alert([] === []); //false
alert({} === {}); //false
alert(null === undefined); //false
alert(null === null); //true

//应该都用=== 严格等于
//判断是为null 还是undefined 可以用===

if与逻辑运算符

if判断

  1. if判断只要求()内 表达式结果是否为truely变量
  2. falsely变量:false “ ” 0 NaN false undefined null;对变量取两次反; !! 结果为false的变量,称为falsely变量
  3. 除了falsely变量外其他都是truely变量
var a = 10;
if(a){
    console.log("条件通过") //条件通过
}
//条件通过

var b = "";
if(b){
    console.log("b通过")
}else{
    console.log("b不通过")  
}
// b不通过

逻辑运算符
  1. 与&&
    1.如果前面的为false,则直接返回false,如果前面的为true,则看后面是否为true
    2.&&前面是truely变量则返回后面的值,前面是falsely变量则直接使用前面的值
    3.在逻辑判断中,&&前面的值为falsely后面的不执行,前面为truely,则看&&后面的值
    4.注意在&&前面如果有报错,则这个代码也会报错,都不执行
var a = 15 || 0;
var b = false || 50;
var c = false || undefined;
var d = 0 || false;
console.log(a); //15   15 转换结果为true ,a的值就是15
console.log(b);  //50  false 转换的结果为false  b的值是50
console.log(c);  // undefined   
console.log(d);  //false

判断对象

if(a&&a.b&&a.b.c){}
if(a?.b?.c){}
如果有a并且有a.b并且有a.b.c

  1. 或||
    同假则假,只要一方为真,结果就是真,如果前面的变量为truely,最终的结果为第一个,如果为falsely,结果为第二个
var a = 15 || 0;
var b = false || 50;
var c = false || undefined;
var d = 0 || false;
console.log(a); //15   15 转换结果为true ,a的值就是15
console.log(b);  //50  false 转换的结果为false  b的值是50
console.log(c);  // undefined   
console.log(d);  //false

原型与原型链
作用:
  1. 在js中实现继承
  2. 实现类(构造函数)实例上方法的扩展
    例子:自定义一个求一组数最大值的方法,并将其挂载到数组原型对象上面
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

准则1:不要需要js默认对象原型上的方法
准则2:不要在js默认对象的原型上添加方法

vue2 数组的双向绑定劫持就是重写了数组的原型上的方法实现的

什么是类?

类是构造对象的一个模板,例如:Array,Object,String,其实本质上是一个函数

什么是实例?

说白一点就是将一个抽象的类给具体化的过程就叫做实例化,比如你要一个人的类,那我就实例化出一个对象,name为张三,age为18,sex为男

什么是原型?

每一个类(构造函数)都有一个显示原型prototype,每一个实例都有一个隐式原型__proto__,
实例化对象的__proto__等于类(构造函数)的prototype
在这里插入图片描述
在这里插入图片描述

什么是原型链?

当我们查找对象的一个属性会先在自身上找,如果找不到就沿着__proto__的__proto__向上查找,我们将proto形成的链条关系称为我们的原型链

类的继承

为了更好的理解原型链,我们来定义两个类分别是Person类与Student类,Person上有name,age属性与eat方法,让学生来继承Person身上的方法

		//01 创建people类
		function People(name, age) {
			this.name = name;
			this.age = age;
		}
		//02 给people 显示原型添加eat方法
		People.prototype.eat = function() {
			console.log(this.name + "正在吃饭");
		}
		//03 创建 学生类继承People 类
		function Student(name, age, no) {
			//执行people构造函数(执行people 函数并把当前的this传入函数,当做people的this)
			People.call(this, name, age);
			//定义学号
			this.no = no;
		}
		//04 让Student 显示原型链继承 People 的原型链
		Student.prototype = Object.create(People.prototype);
		//05 修正Student 显示原型链 上的构造函数
		Student.prototype.constructor = Student;
		//06 在Student 显示原型链添加方法
		Student.prototype.study = function() {
			console.log(this.name + "正在好好学习");
		}
		//07 构建 Student 的实例s1
		var s1 = new Student("菜菜", 18, 9527);

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值