1.手写一个实现const操作符的方法
在JavaScript中,const
是一种声明变量的方式,它用于声明一个只读的常量。一旦使用const
声明了一个变量,你就不能再重新赋值给它,但是这个变量的值可以被修改(如果该值是一个对象或数组,你可以修改对象的属性或数组的元素)。
(1) .使用Object.defineProperty() 限制变量的再次写入,并将定一个这个属性挂载到全局对象上(仅限于个人学习或者面试需要,在真实开发过程中严禁为全局对象随便挂载属性),就可以通过属性名直接访问obj变量,并且可以为obj添加删除属性,但无法重新赋值obj。
function myConst(key,value){
const desc = {
value,
writable: false,
enumerable: true,
configurable: false
}
Object.defineProperty(global,key,desc);
}
myConst('obj',{i:1}) //定义obj
obj.b=3; //可以正常给obj的属性赋值
obj={};// 此代码不生效
console.log(obj) // {i: 1,b: 3}
(2). 使用闭包配合getter,setter实现。
function myConst(value){
let _value = value;
return {
get value() {
return _value;
},
set value(newValue) {
throw new Error('const is not writable')
}
}
}
let obj = myConst(1) // 定义一个名为obj的常量,值为1
obj.b = 1 // 可以为obj添加属性
obj.value = 12 // 修改obj的value属性值就会报错
console.log(obj.value); // 1
2.手写修改this指向的三个方法
(1). call方法。call()
是一个函数对象的方法,它允许你调用一个函数并将一个指定的对象作为当前对象(即this
值)传递给它。call()
方法也可以接受函数参数列表,这些参数将作为函数的参数序列传递给被调用的函数。
Function.prototype.myCall = function (obj,...args) {
obj.fn = this
const res = obj.fn(...args)
delete obj.fn
return res
}
(2). apply方法。apply()方法与call基本相同,唯一不同点在于apply传递参数时在第二个参数位置传入一个数组数组中包含所有原函数调用时需要传的参数。
Function.prototype.myApply = function (obj,args) {
obj.fn = this
const res = obj.fn(...args)
delete obj.fn
return res
}
(3). bind方法。bind
方法创建一个新的函数,当被调用时,将其this
关键字设置为提供的值,并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
Function.prototype.myBind = function (obj,...args) {
const fn = this
return function (...args1) {
const res = fn.apply(obj,args.concat(args1))
return res
}
}
3.手写数组常见方法
(1).forEach()
forEach
是 数组(Array
)的一个方法,用于对数组中的每个元素执行一次提供的函数。这个方法不会修改原数组,并且返回undefined
Array.prototype.myForEach = function (callback) {
// 首先判断callback是否为函数,如果不是则抛出错误
if(typeof callback !== 'function') throw new Error(callback + 'is not a function')
// 获取迭代器对象
const iterator = this[Symbol.iterator]()
let index = 0
while(true) {
const res = iterator.next()
if(res.done) break;
callback.call(this,res.value,index,this)
index++
}
}
(2).map()——面试亲身体验过
map用于通过原数组执行一定逻辑来映射一个新的数组,返回新的数组。
Array.prototype.myMap = function (callback) {
if(typeof callback !== 'function') throw new Error(callback + 'is not a function')
// 获取迭代器对象
const iterator = this[Symbol.iterator]()
let index = 0
const result = []
while(true) {
const res = iterator.next()
if(res.done) break;
const data = callback.call(this,res.value,index,this)
result.push(data)
index++
}
return result
}
(3).filter( )
filter方法用于从原数组中过滤满足条件的元素,返回一个新数组,并且不会改变原数组。
Array.prototype.myFilter = function(callback) {
// 判断callback是否为函数,如果不是则抛出错误
if(typeof callback !== 'function') throw new Error(callback + 'is not a function')
// 获取迭代器对象
const iterator = this[Symbol.iterator]()
let index = 0
const result = []
while(true) {
const res = iterator.next()
if(res.done) break;
const flag = callback.call(this,res.value,index,this)
if(flag) result.push(res.value)
index++
}
return result
}
(4). reduce()
用于将数组中的所有元素归纳(或“减少”)为单个值,一般用于数组求和,配合includes可以实现数组去重。
Array.prototype.myReduce = function (callback,initValue) {
// 判断callback是否为函数,如果不是则抛出错误
if(typeof callback !== 'function') throw new Error(callback + 'is not a function')
// 获取迭代器对象
const iterator = this[Symbol.iterator]()
let index = 0
let result = initValue
while(true) {
const res = iterator.next()
if(res.done) break;
result = callback.call(this,result,res.value,index,this)
index++
}
return result
}
文章所提到的方法即代码实现均为个人拙见,仅供参考。