前端面试个人笔记


(一)Javascript


1. 原始值和引用值类型及区别

数据类型释义
原始值原始值是存储在栈(stack)中的简单数据段 (Undefined,Null,Boolean,Number、String)
引用值引用值是存储在堆中的对象,这个时候变量中存放的是对象的指针,指向对象的内存空间。(Array, Oject, function…Date ,RegExp)

举例

var x = 1; //1就是一个原始值,变量x中存放的就是原始值本身1
var o = {}; //{}这个对象是一个引用值,注意变量o中并没有存放这个对象,而是存放的这个对象的指针

区别

原始类型:不论是变量名还是原始值都在栈中。
当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始变量互不影响。

引用类型:变量名在栈中,数值在堆中,他们中间通过指针进行连接。 当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针, 此时
两者指向的 是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不是通过方法 而是通过 重新赋值
此时 相当于 重新开了一个房间 该值的原指针改变 ,则另外一个 值 不会随他的改变而改变。

2. 判断数据类型typeof、instanceof、Object.prototype.toString.call()、constructor

参考原文链接: https://blog.csdn.net/zjy_android_blog/article/details/81023177.

在写封装的插件或者函数时,常常用到JS的数据类型判断,典型的案例就是深度拷贝函数用到数据类型判断

typeof
console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object     []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object     null 的数据类型被 typeof 解释为 object

能够判断出大多数的数据类型,但是对空数组和null的数据类型判断不够精确。而后的instanceof数据类型判断方法解决了这一问题

instanceof
console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true    
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
————————————————

在这里插入图片描述
可以看出instanceof的类型判断方法是判断对象是否为数字类型实例,只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断.

对于null和undefined浏览器无法判断,实际他们就是对应null型和undefined型。

constructor

在这里插入图片描述
constructor几乎可以完美地将这6种类型进行判断,但是遇到特殊情况,例如:


function Fn(){};
 
Fn.prototype=new Array();
 
var f=new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true 

已经改变过类型的对象,不能准确判断出其原对象。可以解决这个问题的是下面这个大招

Object.prototype.toString.call()
var a = Object.prototype.toString;
 
console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

使用 Object 对象的原型方法 toString ,使用 call 进行狸猫换太子,借用Object的 toString 方法
在这里插入图片描述
即使原型改变了也可以正确判断。

3.类数组与数组的区别与转换

类数组的定义
1)拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理);
2)不具有数组所具有的方法;
javascript中常见的类数组有 arguments对象和 DOM方法的返回结果。比如 document.getElementsByTagName()。

//例如:定义一个类数组
let person = {
	0:"小蜜",
	1:"18",
	length:2
}
console.log(person.length)

区别:

类数组对象不能调用数组原型上的方法。就是:xx.push()、xx.slice()、xx.indexOf() 等等这些方法都不能用。

转换方法:将类数组转为对象

Array.prototype.slice.call(person);
或者
Array.from(person);

4. 数组的常见API

参考来源
https://blog.csdn.net/weixin_33754913/article/details/88695141

unshift push shift pop
  • 会对原数组造成改变
  • unshift()从前添加元素,push()从尾添加元素,返回数组长度
  • shift()删除第0个元素,pop()删除最后一个元素,返回被删除的元素

slice
  • 不会对原来的数组造成改变
  • slice(m, n)返回原数组索引m(包含)到n(不包含)的元素数组。不传参数默认全部截取,只传一个参数,从该位置截取到末位。类似于String.prototype.substring
let arr = [1,2,3,4,5]
console.log(arr.slice()); // [ 1, 2, 3, 4, 5 ]
console.log(arr.slice(1)); // [ 2, 3, 4, 5 ]
console.log(arr.slice(2,4)); // [ 3, 4 ]
console.log(arr); // [1,2,3,4,5]

splice
  • splice(index,howmany,item1,item2…)index表示从第几个位置开始添加元素,howmany代表删除多少元素,如果是0则不删只添,item开始是要填入的元素。若只写index,则从index位置开始删除到末位。
let arr = [1,2,3,4,5];
console.log(arr.splice(2), arr); // [ 3, 4, 5 ] [ 1, 2 ]
console.log(arr.splice(0,1,2), arr); // [ 1 ] [ 2, 2, 3, 4, 5 ]

concat
  • 拼接不改变原数组
let arr = [1,2,3], arr1 = [4];
console.log(arr.concat(arr1, 5), arr); // [ 1, 2, 3, 4, 5, ] [ 1, 2, 3 ]
console.log([...arr, ...arr1, 5]); // [ 1, 2, 3, 4, 5 ] (对象也可以这样拼接,但重复的会覆盖,相当与 Object.assign)

of 和 from
  • of()类似于new Array(),但后者如果传入一个参数,则是设置数组长度。 from()
  • 把伪数组转换为真数组,类似于[].slice.call()(或者写成Array.prototype.slice.call())
  • 伪数组有DOM集、arguments、{0: ‘zero’, 1: ‘one’, length: 2}

判断数组的方法有
  • xx instanceof Array
  • Array.isArray()
  • Object.prototype.toString.call() === ‘[object Array]’

indexOf 和 includes
  • indexOf() 返回索引,不存在就返回 -1。inclues()返回布尔值。
  • NaN 不能通过indexOf()判断,它是通过“===”比较的。
arr = [1, '2', null, NaN];
arr.indexOf(NaN); // -1
arr.includes(NaN); // true

filter、find 和 findIndex
  • filter() 返回数组。find() 返回值,不存在就返回 undefined。 findIndex() 返回第一个匹配到的索引,不存在就返回 -1。
let arr = [1, '2', null, NaN];
arr.filter(item => typeof item === 'number'); // [1, NaN]
arr.find(item => typeof item === 'number'); // 1
arr.findIndex(item => typeof item === 'number'); // 0
5.bind、call、apply的区别

参考链接:https://www.jb51.net/article/99797.htm

  • 三种方法都是用于改变this的指向
  • call()和apply()唯一区别是参数不一样,call可以接收一个参数列表,而apply只接受参数数组
  • bind()是返回一个新函数,供以后调用,而apply()和call()是立即调用。
#三者实现示例:
function keith(a, b) {
	return a + b;
	}
console.log(keith.apply(null,[1,4])); //5
console.log(keith.call(null,1,4)); //5
console.log(keith.bind(null, 1, 4)); //keith()
console.log(keith.bind(null, 1, 4)()); //5
6. new的原理
  1. 如何正确判断this?
  2. 闭包及其作用
  3. 原型和原型链
    10.prototype与__proto__的关系与区别
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

然小梨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值