JavaScript 原型和原型链

就在我第100次以为我弄懂了原型和原型链,第101次又被面试官问到自闭。

先说结论:原型链是基于__proto__形成的,继承是通过prototype(原型)实现的。

那么,什么是prototype,什么是__proto__,两者关系又是怎样的呢?

prototype

  • prototype 是只有函数才有的属性
  • 函数的prototype指向一个对象(原型对象),其他对象可以通过它实现属性和方法的继承。

proto

  • __proto__ 是浏览器非标准属性,只有部分浏览器实现了此属性,对应的标准属性是[[Prototype]]
  • __proto__ 是每个对象都具有的属性
  • __proto__连接起来的对象,组成的一个有继承关系的链条,叫做"原型链"。

proto & prototype

  • 对象的__proto__属性指向对象的构造函数的prototype属性,也就是原型对象。
  • 由于每个 JavaScript 函数实际上都是一个 Function 对象(MDN),因此函数也有__proto__属性,函数的__proto__属性,指向Function.prototype

那么,普通函数、构造函数、Object、Function之间到底有什么关系呢?它们的__proto__prototype之间的指向又是怎样的呢?

// 定义函数 a,a的本质是由Function函数构造出的js对象
function a(){}

// 对象的__proto__属性指向其构造函数的prototype属性,下面为true
console.log(a.__proto__ === Function.prototype) // true

// 所有的函数都是Function生成的,Object构造函数和Function自己也不例外,它们的__proto__属性都指向Function.prototype,所以下面两个为true
console.log(Object.__proto__ === Function.prototype); // true
console.log(Function.__proto__ === Function.prototype); // true

// Function.prototype是一个对象,它的__proto__属性指向原型链的最顶端Object.prototype
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

看下面图会更加清晰一些

完整的原型关系图

弄懂了了这些,再看下面的题目,就是 so easy~

题目1

var A = function() {};
A.prototype.n = 1;
var b = new A();
A.prototype = {
  n: 2,
  m: 3
}
var c = new A();

console.log(b.n); // 1
console.log(b.m); // undefined

console.log(c.n); // 2
console.log(c.m); // 3

题目2

var F = function() {};

Object.prototype.a = function() {
  console.log('a');
};

Function.prototype.b = function() {
  console.log('b');
}

var f = new F();

f.a(); // a
f.b(); // f.b is not a function

F.a(); // a
F.b(); // b

题目3

function Person(name) {
    this.name = name
}
let p = new Person('Tom');

p.__proto__等于什么?---> Person.prototype

Person.__proto__等于什么?---> Function.prototype

题目4

var foo = {},
    F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';

console.log(foo.a); // value a
console.log(foo.b); // undefined

console.log(F.a); // value a
console.log(F.b); // value b
posted @ 2020-04-06 22:43  dora_zc  阅读(165)  评论(0编辑  收藏  举报