Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Genzhen opened this issue Jun 22, 2020 · 6 comments
Open

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

Genzhen opened this issue Jun 22, 2020 · 6 comments

Comments

@Genzhen
Copy link
Collaborator

Genzhen commented Jun 22, 2020

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

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

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

@Genzhen
Copy link
Collaborator Author

Genzhen commented Jun 22, 2020

答案
false

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

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

@Genzhen Genzhen closed this as completed Jul 21, 2020
@Genzhen Genzhen reopened this Jul 29, 2020
@jojo1900
Copy link

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

@Alfred-kai
Copy link

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

instanceOf的实现原理原来是这样

@liuyuan22
Copy link

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

@zengxiaoluan
Copy link

zengxiaoluan commented Apr 8, 2021

先来看下 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
Copy link

zengxiaoluan commented Apr 22, 2021

如何把 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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants