1. call apply bind的区别?
相同点: 都可以改变函数调用的this指向
不同点:
call和apply的用法几乎相同,唯一不同就是参数不同。call只能一个一个参数传入,apply参数是一个数组。
bind的传参方式和call相同,但是改变调用函数的指向并返回一个新的函数,之后再调用这个函数时候this就指向bind绑定的第一个参数
call语法
fun.call(thisArg,arg1,arg2,...)
thisArg是fun函数运行时指定的this值(在非严格模式下,指定为null或undefined时会自动指向全局对象)
arg1,arg2,...是指定的参数列表
apply语法
fun.apply(thisArg, [argsArray])
thisArg是fun函数运行时指定的this值(在非严格模式下,指定为null或undefined时会自动指向全局对象)
argsArray是一个数组或类数组对象,数组中的元素将作为单独的参数传给fun函数,如果 argsArray为null或undefined时表示不需要传入任何参数。
示例:
数组没有max方法,可以使用Math对象上的max方法
const arr = [1,2,3,4,5,6];
const max = Math.max.apply(null,arr); // 6
bind语法
fun.bind(thisArg,arg1,arg2,...)
thisArg当绑定函数被调用时,该参数会作为原函数运行时的this指向。当使用new 操作符调用绑定函数时,该参数无效。
arg1, arg2, ...当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
// 如果你某个函数绑定新的this指向并且固定先传入几个变量可以在绑定的时候就传入,之后调用新函数传入的参数都会排在之后
const obj = {}
function test(...args) {
console.log(args);
}
const newFn = test.bind(obj, 1,2);
newFn(3,4); // [1,2,3,4]
使用场景
当一个函数需要改变this指向时
且参数较少时可以使用call
如果参数较多,可以将参数整理到一个数组,使用apply
如果想生成一个新函数长期绑定某个对象时,可以使用bind
2. 数组去重
方法一:
这是个没有什么技术含量的方法(使用了ES6 Set数据结构)!
let arr = [1,1,1,1,2,3,4,5,5,6];
arr = [...new Set(arr)]; // [1,2,3,4,5,6]
方法二:
for循环嵌套for循环
function unique(arr){
for(let i = 0; i<arr.length; i++) {
for(let j = i+1; j < arr.length; j++) {
if(arr[i] === arr[j]){
arr.splice(j,1); // 去除重复的这个
j--;
}
}
}
return arr;
}
方法三
使用indexOf方法,或数组的includes方法
function unique(arr) {
let arr1 = [];
for(let i=0; i<arr.length; i++) {
if(arr1.indexOf(arr[i]) === -1) { // !arr1.includes(arr[i])
arr1.push(arr[i]); // 如果arr1中不存在该元素则push进arr1
}
}
return arr1;
}
方法四
利用sort排序后,相邻元素进行对比
function unique(arr) {
arr.sort( (a,b) => a-b);
for(let i=0; i< arr.length-1; i++){
if(arr[i] === arr[i+1]) {
arr.splice(i+1,1);
}
}
return arr;
}
…
当然不只这几种方法。。欢迎评论补充
3. http状态码(点击跳转)
4. CSS弹性布局(点击跳转)
5.position属性有哪些值,分别有什么含义
position属性规定元素的定位类型
属性值 描述
absolute 生成绝对定位的元素。相对于除了static定位以外的第一个父元素定位
fixed 生成绝对定位的元素,相对于浏览器窗口定位
relative 生成相对定位元素,相对于自己原来的位置定位
static 默认值。没有定位,元素出现在正常流中(忽略 top, bottom, left, right 或者 z-index 声明)
inherit 继承父元素position的值
6. const和let的区别,可以改变const定义对象某个属性吗
const与let都只在声明的块级作用域内有效
let声明的变量可以改变,值和类型都可以改变,且可以先声明,后赋值。
const声明一个常量,值不可以改变,且一旦声明就得赋值。
对于const声明一个引用类型的变量(如:数组,对象),变量名不指向数据,而是指向引用类型数据所在的地址(即变量保存的是指向这个引用类型的指针),因此可以改变const定义对象的某个属性值。
7. this的理解, 如何改变this的指向
this值函数运行时所在的环境(即调用的对象)
可以理解为谁调用函数,this就指向谁
可以上述序号1的call,apply,bind方法改变this指向
8. let和var的区别,let的产生背景?
let声明变量会形成块级作用域,var不能
let声明变量只能先声明后使用(暂时性死区),即let不存在变量提升
示例:
{
let a =1;
}
console.log(a); // a is not defined
9. var的变量提升底层原理是什么
JS引擎的工作方式:
先解析代码,获取所有声明的变量
然后再运行
也就是分为预处理和执行两个阶段
变量提升的定义: 所有的变量声明语句会被提升到声明变量所在作用域的头部
定义与赋值分离
示例:
console.log(a); // 报错 a is not defined
console.log(b); // undefined
var b = 1;
上面的代码相当于:
var b;
console.log(b); // undefined
b = 1;
10. 箭头函数,箭头函数的特点
相比普通函数更简洁的语法
本身没有this,捕获其所在上下文(作用域)的this值,作为自己的 this 值
不能使用new
不绑定arguments,用rest参数...解决
使用call()和apply()调用
箭头函数没有原型属性
不能简单返回对象字面量
箭头函数不能当做Generator函数,不能使用yield关键字
|
|