前端问题整理

it2026-01-07  8

前端问题整理

1. call和apply的区别是什么?哪个性能更好一些?

call和apply都是function原型上的方法,用来改变this的指向

// call传参是一个一个传 // 参数的个数不固定 fn.call(obj, 10, 20 ,30) // apply传参是已数组的形式传 // 参数是固定的 fn.apply(obj, [10, 20, 20]) // 参数的个数3个以内2个性能差不多,3个以上call性能好 let arr = [10, 20, 30], obj = []; function fn(x, y, z){} fn.apply(obj, arr); fn.call(obj,...arr); // console.time 可以测试出一段程序的执行时间 console.time("A"); for (let i = 0; i < 1000000000; i++) {} console.timeEnd("A");

2. 实现(5).add(3).minus(2) 使出去结果为6

// 方式1 Number.prototype.add = function(num = 0){ return this + num; } Number.prototype.minus = function(num = 0){ return this - num; } console.log((5).add(3).minus(2)); // 6 // 方式2 function add(n = 0){ return this + n; } function minus(n = 0){ return this - n; } ["add", "minus"].forEach(item => { Number.prototype[item] = eval(item) }) console.log((5).add(3).minus(2)); // 6

3. 箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用new生成实例。name箭头函数可以么?为什么?

箭头函数语法上比普通函数更加简洁箭头函数没有自己的this,他里面出现的this是继承函数所在的上下文中的this(使用call/apply等认可方式都无发改变this的指向)箭头函数里没有arguments,只能基于…arg获取传递的参数集合(数组)箭头函数不能被new执行(因为箭头函数没有this也没有prototype) // 箭头函数语法上比普通函数更加简洁 function fn(x) { return function (y) { return x + y } } let fn = x => y => x + y

4. 编写代码实现图片的懒加载

处理方案:

把所有需要延迟加载的图片用一个盒子包起来,设置宽高和默认占位图开始让所有的img的src为空,把真实图片的地址放到img的自定义属性上,让img隐藏等到所有其他资源都加载完成后,我们再开始加载图片对于很多图片,需要当页面滚动时,当前图片区域完全显示出来以后再加载真实图片

5. 编写一个程序,将数据扁平化,并除去其中重复部分数据,最终得到一个升序且不重复的数组

let arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13]]]] arr = arr.flat(Infinity); arr = Array.from(new Set(arr)).sort((a, b) => a-b); console.log(arr);

6. 手写new

function Dog(name) { this.name = name; } Dog.prototype.bark = function() { console.log("wangwang"); } Dog.prototype.sayName = function() { console.log("my name is" + this.name); } /* 1. 像普通函数执行一样,形成一个私有的作用域 + 形参赋值 + 变量提升 2. 默认创建一个对象, 让函数中的this指向这个对象,这个对象就是当前类的一个实例 3. 代码执行 4. 默认把创建的对象返回 */ function _new(Fn, ...arg) { // 创建一个空对象,让他的原型链指向Fn.prototype(作为Fn的一个实例) let obj = Object.create(Fn.prototype) FN.call(obj, ...arg); return obj; } //let sanmao = new Dog('三毛'); //需要做到这个效果 let sanmao = _new(Dog, '三毛'); sanmao.sayName(); sanmao.bark();

==比较过程

==进行比较的时候,如果左右两边数据类型不一样,则先转换为相同的数据类型,然后在进行比较

{} == {} 两个对象进行比较,比较的是堆内存地址

null == undefined 是相等的 ,null === undefined 不相等

NaN == NaN 不相等,NaN和谁都不相等

[12] == “12” 对象和字符串比较,是把对象toString()转换为字符串后再进行比较

剩余所有情况在进行比较的时候,都是转换为数字(前提数据类型不一样)

对象转数字:先转换成字符串,然后再转换为数字

字符串转数字:只要出现一个非数字字符,结果就是NaN

布尔转数字:true->1 false->0

null转数字0

undefined转数字NaN

// a等于什么可以打出ok var a = ?; if(a == 1 && a == 2 && a == 3){ console.log("ok") } // ======方式1========= var a = { n:0, toString: function(){ return ++this.n } }; if(a == 1 && a == 2 && a == 3){ console.log("ok"); } // ======方式2========= var a = [1,2,3]; a.toString = a.shift if(a == 1 && a == 2 && a == 3){ console.log("ok"); } // ======方式3========= Object.defineProperty(window, 'a', { get: function(){ this.value ? this.value++: this.value = 1; return this.value; } }); if(a == 1 && a == 2 && a == 3){ console.log("ok"); }
最新回复(0)