乐趣区

一道有趣的面试题

function yideng(){}
const a = {}, b = Object.prototype;
console.log(a.prototype === b);
console.log(Object.getPrototypeOf(a) === b);
console.log(yideng.prototype === Object.getPrototypeOf(yideng));
// 写出执行后果

答案:false true false

// 知识点
__proto__(隐式原型)与 prototype(显式原型)
1)是什么?
①显式原型 explicit prototype property:
每一个函数在创立之后都会领有一个名为 prototype 的属性,这个属性指向函数的原型对象。(须要留神的是,通过 Function.prototype.bind 办法结构进去的函数是个例外,它没有 prototype 属性)
②隐式原型 implicit prototype link:
JavaScript 中任意对象都有一个内置属性 [[prototype]],在 ES5 之前没有规范的办法拜访这个内置属性,然而大多数浏览器都反对通过__proto__来拜访。ES5 中有了对于这个内置属性规范的 Get 办法 Object.getPrototypeOf()。(留神:Object.prototype 这个对象是个例外,它的__proto__值为 null)
③二者的关系:
隐式原型指向创立这个对象的函数 (constructor) 的 prototype

2)作用是什么?
①显式原型的作用:用来实现基于原型的继承与属性的共享。
②隐式原型的作用:形成原型链,同样用于实现基于原型的继承。举个例子,当咱们拜访 obj 这个对象中的 x 属性时,如果在 obj 中找不到,那么就会沿着__proto__顺次查找。

3)__proto__的指向:
__proto__的指向到底如何判断呢?依据 ECMA 定义 ‘to the value of its constructor’s “prototype” ‘ —- 指向创立这个对象的函数的显式原型。
所以要害的点在于找到创立这个对象的构造函数,接下来就来看一下 JS 中对象被创立的形式,一眼看过来仿佛有三种形式:(1)对象字面量的形式(2)new 的形式(3)ES5 中的 Object.create()。
然而实质上只有一种形式,也就是通过 new 来创立。为什么这么说呢,首先字面量的形式是一种为了开发人员更不便创建对象的一个语法糖,实质就是 var o = new Object(); o.xx = xx;o.yy=yy;

// 解析:

1)a.prototype === b =>false
prototype 属性是只有函数才特有的属性,当你创立一个函数时,js 会主动为这个函数加上 prototype 属性,值是一个空对象。而实例对象是没有 prototype 属性的。所以 a.prototype 是 undefined, 第一个后果为 false。

2)Object.getPrototypeOf(a) === b =>true
首先要明确对象和构造函数的关系,对象在创立的时候,其__proto__会指向其构造函数的 prototype 属性
Object 实际上是一个构造函数(typeof Object 的后果为 ”function”), 应用字面量创建对象和 new Object 创建对象是一样的,所以 a.__proto__也就是 Object.prototype,所以 Object.getPrototypeOf(a) 与 a.__proto__是一样的,第二个后果为 true

3)yideng.prototype === Object.getPrototypeOf(yideng) =>false
关键点:f.prototype 和 Object.getPrototypeOf(f)说的不是一回事

①f.prototype 是应用应用 new 创立的 f 实例的原型:
f.prototype === Object.getPrototypeOf(new f()); // true

②Object.getPrototypeOf(f)是 f 函数的原型:
Object.getPrototypeOf(f) === Function.prototype; //true

所以答案是 false

退出移动版