答案
false
解析
a instanceof b 用于检测a是不是b的实例。如果题目f中没有return f,则答案明显为true;而在本题中new f()其返回的结果为f的函数对象,其并不是f的一个实例。
function f(){}
console.log(new f() instanceof f);
// 答案:true
new f() 返回的是 f 这个函数对象。
而 o instanceOf O的实现原理是,检测o的原型链上有没有O.prototype 即 o.__proto__ == O.prototype || o.__proto__.__proto__ == O.prototype。调试可以看出,两者并不相同。
而 o instanceOf O的实现原理是,检测o的原型链上有没有O.prototype 即 o.proto == O.prototype || o.proto.proto == O.prototype。调试可以看出,两者并不相同。
instanceOf的实现原理原来是这样
如果函数返回值是Object类型,那么new操作符会返回这个Object类型的值。如果返回值不是Object类型(不写return就是返回undefined),那么new操作符会返回该函数的一个实例
先来看下 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
如何把 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)
Most helpful comment
new f() 返回的是 f 这个函数对象。
而 o instanceOf O的实现原理是,检测o的原型链上有没有O.prototype 即 o.__proto__ == O.prototype || o.__proto__.__proto__ == O.prototype。调试可以看出,两者并不相同。