Skip to content

Day11:写出执行结果,并解释原因 #47

@Genzhen

Description

@Genzhen
Collaborator
function f(){
      return f;
 }
console.log(new f() instanceof f);
// 写出执行结果,并解释原因

每日一题会在下午四点在交流群集中讨论,五点小程序中更新答案
欢迎大家在下方发表自己的优质见解
二维码加载失败可点击 小程序二维码

扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。

Activity

Genzhen

Genzhen commented on Jun 22, 2020

@Genzhen
CollaboratorAuthor

答案
false

解析
a instanceof b 用于检测a是不是b的实例。如果题目f中没有return f,则答案明显为true;而在本题中new f()其返回的结果为f的函数对象,其并不是f的一个实例。

function f(){}
 console.log(new f() instanceof f);
// 答案:true
jojo1900

jojo1900 commented on Jan 29, 2021

@jojo1900

new f() 返回的是 f 这个函数对象。
而 o instanceOf O的实现原理是,检测o的原型链上有没有O.prototype 即 o.proto == O.prototype || o.proto.proto == O.prototype。调试可以看出,两者并不相同。

Alfred-kai

Alfred-kai commented on Mar 2, 2021

@Alfred-kai

而 o instanceOf O的实现原理是,检测o的原型链上有没有O.prototype 即 o.proto == O.prototype || o.proto.proto == O.prototype。调试可以看出,两者并不相同。

instanceOf的实现原理原来是这样

liuyuan22

liuyuan22 commented on Mar 17, 2021

@liuyuan22

如果函数返回值是Object类型,那么new操作符会返回这个Object类型的值。如果返回值不是Object类型(不写return就是返回undefined),那么new操作符会返回该函数的一个实例

zengxiaoluan

zengxiaoluan commented on Apr 8, 2021

@zengxiaoluan

先来看下 new 关键字做了什么:

function mockNew() {
  let Con = [].shift.call(arguments)
  let o = {}

  let res = Con.apply(o, arguments)
  if(res instanceof Object) return res
  
  o.__proto__ = Con.prototype
  return o
}

上面的函数 mockNew 模拟了 new 关键字创建一个实例的过程。首先拿到传入参数的构造函数,创建了一个命名为 o 的对象;执行构造函数 Con,将其 this 绑定为 o;最关键的在于,会检测构造函数返回的结果是不是 Object 对象的实例,如果是的话会返回构造函数的执行结果,否则返回创建的 o

再来看下 instanceof 操作符做了什么:

function mockInstance(proto, parent) {
    if(proto === null) return false
    while(proto) {
        if(parent.prototype === proto) return true
        else proto = proto.__proto__
    }
    return false
}

上面的函数表明了 instanceof 的原理,沿着原型链一层一层往上找,直到原型匹配或者原型为 null 为止。

配合题目来理解:

function f() {
      return f; // 函数 f 继承自对象,所以 new 之后会返回函数本身
 }
console.log(new f() instanceof f); // 函数的上层原型链是 native code,native code 上层的原型链是 Object,不和 f.prototype 相等,所以返回值为 false
zengxiaoluan

zengxiaoluan commented on Apr 22, 2021

@zengxiaoluan

如何把 URL 里的 queryString 转化成一个对象?如 ?a=b&c=1,转成 { a: 'b', c: 1 },我们来介绍 2 种方式。

第一种使用正则:

var url = 'https://www.baidu.com/s?wd=%E6%B5%8B%E8%AF%95&rs&rsv_spt=1&rsv_spt=2&rsv_iqid=0xec504f1800025d7f&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&oq=test&rsv_btype=t&inputT=2899&rsv_t=e5aaY3xRbIqZc93Af9wRS9O36UFIWlR2BVTmZTGoNcnBP%2BJGFg19WmoA%2B8aIBIUw9lU2&rsv_sug3=18&rsv_sug1=13&rsv_sug7=100&rsv_pq=afe6a1b00001e182&rsv_sug2=0&rsv_sug4=3654'
var reg = /[?|&]([^&=]+)=?([^&]*)/g
var res = url.matchAll(reg)
var obj = {}

for(let item of res) {
    let k = item[1]
    let v = decodeURIComponent(item[2]) || true
    if(!isNaN(v) && v !== true) v = +v

    let valueInObj = obj[k]
    if(!valueInObj) obj[k] = v
    else {
        if(Array.isArray(valueInObj)) valueInObj.push(v)
        else {
            obj[k] = [valueInObj, v]
        }
    }
}
console.log(obj)

第二种使用原生的 api URL

var anotherUrl = new URL(url)
var anotherObj = {}
for(let [k, v] of anotherUrl.searchParams.entries()) {
    v = v || true
    if(v !== true && !isNaN(v)) v = +v
    if(!anotherObj[k]) {
        anotherObj[k] = v
    } else {
        anotherObj[k] = Array.isArray(anotherObj[k]) ? [...anotherObj[k], v] : [anotherObj[k], v]
    }
}
console.log(anotherObj)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @zengxiaoluan@jojo1900@liuyuan22@Genzhen@Alfred-kai

        Issue actions

          Day11:写出执行结果,并解释原因 · Issue #47 · lgwebdream/FE-Interview