【无标题】

1、深度比较两个对象是否相等
所有不相等的返回false

function diff (obj1, obj2) {
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length !== keys2.length) {
        return false;
    }
    else {
        for (let key in obj1) {
            if (!obj2.hasOwnProperty(key)) {
                return false;
            }
            //类型相同
            if (typeof obj1[key] === typeof obj2[key]) {
                //两个对象同为引用类型
                if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
                    const equal = diff(obj1[key], obj2[key]);
                    if (!equal) {
                        return false;
                    }
                }
                //两个对象同为基础数据类型
                if (typeof obj1[key] !== 'object' && typeof obj2[key] !== 'object' && obj1[key] !== obj2[key]) {
                    return false;
                }
            }
            else {
                return false;
            }
        }
    }
    return true;
}

hasOwnProperty: 检查对象自身属性;
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。

引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
2、实现eventEmitter

export default class EventEmitter {
  constructor() {
    this.event = {};
    this.maxListerners = 10;
  }
  // 监听
  on(type, listener) {
    if (this.event[type]) {
      if (this.event[type].length >= this.maxListerners) {
        console.error('同一个监听器最多被十个对象监听,否则可能造成内存泄漏.\n');
        return;
      }
      this.event[type].push(listener);
    } else {
      this.event[type] = [listener];
    }
  }
  //发送监听
  emit(type, ...rest) {
    if (this.event[type]) {
      this.event[type].map(fn => fn.apply(this, rest));
    }
  }
  //移除监听器
  removeListener(type) {
    if (this.event[type]) {
      delete this.event[type];
      console.log(this.event);
    }
  }
  //移除所有的监听器
  removeAllListener() {
    this.event = {};
  }
}

3、生成随机长度混合的密码

const randomFunc = {
    lower: getRandomLower,
    upper: getRandomUpper,
    number: getRandomNumber,
    symbol: getRandomSymbol
}
function generatePassword(lower, upper, number, symbol, length) {
    let generatedPassword = ''
    //密码的组成是小写+大写+数字+符号
    const typesCount = lower + upper + number + symbol
    const typesArr = [{lower}, {upper}, {number}, {symbol}].filter(item => Object.values(item)[0])
    
    if(typesCount === 0) {
        return ''
    }
     //每次循环输出一个typesCount长度的字符串,i+typesCount
    for(let i = 0; i < length; i += typesCount) {
        typesArr.forEach(type => {
            const funcName = Object.keys(type)[0]
            generatedPassword += randomFunc[funcName]()
        })
    }

    const finalPassword = generatedPassword.slice(0, length)

    return finalPassword
}

function getRandomLower() {
    return String.fromCharCode(Math.floor(Math.random() * 26) + 97)
}

function getRandomUpper() {
    return String.fromCharCode(Math.floor(Math.random() * 26) + 65)
}

function getRandomNumber() {
    return String.fromCharCode(Math.floor(Math.random() * 10) + 48)
}

function getRandomSymbol() {
    const symbols = '!@#$%^&*(){}[]=<>/,.'
    return symbols[Math.floor(Math.random() * symbols.length)]
}
//调用
var hasLower = true; var hasUpper = true; var hasNumber = true; var hasSymbol = true; var length = 10;
generatePassword(hasLower, hasUpper, hasNumber,hasSymbol,length)
//输出
'tD1*vF8,yN'

4、react为什么需要key
key作用: 判断元素是新创建的还是被移动的元素,从而减少不必要的元素渲染

5、parseInt遇上map

['1','2','3'].map(parseInt) 输出为[1,NaN,NaN]

解析: parseInt 函数只需两个参数parseInt(value, radix),而map的回调函数需要三个参数callback(currentValue,index,array);

parseInt的第二个参数是一个2-36之间的整数值,用于制定转换中采用的基数。

  • 如果省略该参数或者值为0,则当作十进制来解析。
  • 该参数小于2或者大于36,则parseInt返回NaN
  • 转换失败也返回NaN。

上述题目:parseInt(‘1’,0)的结果是当作十进制解析,返回1;parseInt(‘2’,1)的第二个参数非法,返回NaN;parseInt(‘3’,2)会当作二进制来解析,但是‘3’在二进制中是非法的,转换失败,返回NaN。

map方法

var ary = Array(3);
ary[0] = 2;
ary.map(function(elem){
return '1';
});
输出['1',undefined,undefined]

map方法: 给原数组中的每个元素都按顺序调用一次callback函数。callback每次执行后的返回值组合起来形成一个新数组。callback函数只会在有值的索引上被调用;从来没被赋值或者使用delete删除的索引则不会被调用。

6、

var val = 'smtg';
console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');
输出Something

解析: + 运算符优先级大于? 所以上述表达式相当于’value is’+true ? ‘Something’: ‘Nothing’

7、javascript强制转换
题目

var a = [0];
if([0]){
console.log(a == true);
}else{
 console.log('wut')
}
输出false

当[0]需要被强制转换成Boolean的时候被认为是true。所以进入第一个if语句;
a == true 的转换规则,由ES规范指出,是: == 相等中,如果有一个操作符是布尔类型,会先把他转成数字,所以
a == true 相当于 [0] == 1;同时规范指出如果其他类型和数字比较,会尝试把这个类型转成数字再进行宽松比较,而对
象会先调用它的toString()方法,此时[0[会变成‘0’,然后将该字符串转成0,0==1结果显然false

[] == [] 输出false

如果比较的两个对象指向的是同一个对象返回true,否则返回false
8、二分查找

//循环不变式 guess 等于l r中间位置
const bsearch = (A, x) => {
  let l = 0
  let r = A.length - 1
  let guess
  while (l <= r) {
    console.log('find')
    guess = Math.floor((l + r) / 2)
    if (A[guess] === x) return guess
    if (A[guess] > x) r = guess - 1
    else l = guess + 1
  }
  return -1
}

let arr = [1, 2, 3, 4, 5, 6, 7, 8]
console.log(bsearch(arr, 6)) // 5

https://juejin.cn/post/6844903575559077895 (重要!基本涵盖了所有的js手写题和代码实现)

9、react 子组件向父组件传递值

  1. 父组件给子组件传递一个函数
  2. 子组件通过props获取该函数并给该函数附上参数
  3. 父组件通过函数拿到子组件传递的值
    https://blog.csdn.net/w544924116/article/details/119565219
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值