你的浏览器还没开启 Javascript 功能!

分享两道面试题

前几天遇到两个前端面试题,要写代码的那种,然后我都没做对…记录一下

第一题

JavaScript 采用原型继承,即一个对象继承自另外一个对象,另外一个对象再继承自别的对象,依此往复。请写一个通用的 JavaScript 函数,来找出某个对象身上的某个属性继承自哪个对象。

解答: 实际上是在考察如何判断一个对象上的属性是本身的还是通过继承来的,使用 hasOwnPropertygetPrototypeOf 方法即可

function getPrototype(obj, key) {
  if (obj.hasOwnProperty(key)) {
    return obj
  }

  return getPrototype(Object.getPrototypeOf(obj), key)
}


const obj = { a: 'a' }
const o1 = Object.create(obj)
o1.b = 'b'

console.log(o1.a) // a
console.log(o1.b) // b

console.log(o1.hasOwnProperty('a')) // false
console.log(o1.hasOwnProperty('b')) // true

console.log(getPrototype(o1, 'a')) // { a: 'a' }
console.log(getPrototype(o1, 'b')) // { b: 'b' }

相关文章

继承与原型链

第二题

URLSearchParams() 可以解析和处理URL参数,目前兼容性一般,请实现 class URLSearchParams 的 polyfill。

searchParams = new URLSearchParams("foo=1&bar=2")
// 或者这样传入
searchParams = new URLSearchParams({foo: "1", bar: "2"})
// 实例支持 get()、set()、has()、append() 四个方法

// 支持以下方式
searchParams.get("foo") // 1
searchParams.set("foo", "10")
searchParams.has("bar")
searchParams.append("foo", "100")

解答:简单实现了下,看了 Github 上 URLSearchParams 的 polyfill 代码,发现这个还是有点复杂的

class URLSearchParams {
  constructor (query) {
    this._query = {}

    if (typeof query === 'string') {
      if (query.startsWith('?', 0)) {
        query = query.slice(1)
      }

      query.split('&').forEach(pair => {
        const params = pair.split('=')
        const key = params[0]
        const val = params[1]

        this._query[key] = val
      })
    } else {
      for (let [key, value] of Object.entries(query)) {
        this._query[key] = query[key]
      }
    }
  }

  get (key) {
    return this.has(key) ? this._query[key] : null
  }

  set (key, val) {
    this._query[key] = encodeURIComponent(val)
    return true
  }

  has (key) {
    return key in this._query
  }

  append (key, val) {
    const value = Array.isArray(val) ? val.join(',') : val
    if (key in this._query) {
      this._query[key].push(value)
    } else {
      this._query[key] = value
    }
    return this._query[key]
  }
}

const mysp1 = new URLSearchParams('a=aaa&b=bbb')
const mysp2 = new URLSearchParams({ c: 'ccc', d: 'ddd' })

console.log(mysp1) // URLSearchParams { _query: { a: 'aaa', b: 'bbb' } }
console.log(mysp1.get('a')) // aaa
console.log(mysp1.set('c', 'ccc')) // true
console.log(mysp1.has('d')) // false
console.log(mysp1.append('e', 'eee')) // eee
console.log(mysp1) // { _query: { a: 'aaa', b: 'bbb', c: 'ccc', e: 'eee' } }

console.log(mysp2) // URLSearchParams { _query: { c: 'ccc', d: 'ddd' } }
console.log(mysp2.get('c')) // ccc
console.log(mysp2.set('d', 'ddd2')) // true
console.log(mysp2.has('d')) // true
console.log(mysp2.append('f', 'fff')) // fff
console.log(mysp2) // URLSearchParams { _query: { c: 'ccc', d: 'ddd2', f: 'fff' } }

相关文章

URLSearchParams docs

URLSearchParams polyfill

总结

自己太菜了,基础知识由于没有去回顾所以忘的很多,继续加油吧。