f通过new关键词进行函数调用,之后无论如何都会返回一个与F关联的普通对象(因为不是通过函数构造创建的对象,所以不是函数对象,也就取不到b了

发布时间 2023-11-14 20:05:28作者: 龙陌
var F=function(){};
Object.prototype.a=function(){};
Function.prototype .b=function(){};
var f=new F();

关于这段代码的描述,正确的是:

A
f能取到a,但取不到b

B
f能取到a,b

C
F能取到b,不能取到a

D
F能取到a,不能取到b

正确答案:A

网上有一道美团外卖的面试题是这样的:
Function.prototype.a = 'a';
Object.prototype.b = 'b';
function Person(){};
var p = new Person();
console.log('p.a: '+ p.a); // p.a: undefined
console.log('p.b: '+ p.b); // p.b: b 问为什么?

有不少同学第一眼看上去就觉得很疑惑,p不是应该继承了Function原型里面的属性吗,为什么p.a返回值是undefined呢?
其实,只要仔细想一想就很容易明白了,
Person函数才是Function对象的一个实例,所以通过Person.a可以访问到Function原型里面的属性,
但是new Person()返回来的是一个对象,它是Object的一个实例,是没有继承Function的,所以无法访问Function原型里面的属性。
但是,由于在js里面所有对象都是Object的实例,所以,Person函数可以访问到Object原型里面的属性,Person.b => 'b'

这个问题涉及到js的原型继承

  1. f.proto ===
    f[的构造函数].prototype === F.prototype

  2. F.prototype.proto ===
    (F.prototype)[的构造函数].prototype === Object.prototype (所以a能够 通过f.a访问)

  3. f.constructor === F

  4. F.proto ===
    F[的构造函数].prototype === Function.prototype (所以b可以通过,
    f.constructor.b访问到)

注意:

(F.prototype)[的构造函数] === Object

F[的构造函数] === Function

多啰嗦一句( js 的继承靠的是__proto__,并不是prototype)

所有普通对象都源于这个Object.prototype对象,只要是对象,都能访问到a,
f通过new关键词进行函数调用,之后无论如何都会返回一个与F关联的普通对象(因为不是通过函数构造创建的对象,所以不是函数对象,也就取不到b了

最详尽的 JS 原型与原型链终极详解,没有「可能是」。(一)