我对JavaScript原型和原型链的理解

目前新型冠状病毒传染严重,做好自我保护包括:保持基本的手部和呼吸道卫生,坚持安全饮食习惯,并尽可能避免与任何表现出有呼吸道疾病症状(如咳嗽和打喷嚏等)的人密切接触

在了解原型链之前我们先来看一个简单的栗子

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 function

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

可以看到 f.b() 返回的是 f.b() is not function 这是因为new 出来的实例是一个对象,只会继承 Object 原型上的方法,而不会继承 Function 原型上的方法,用一张图可以看出关系如下

image.png

所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)
所有函数拥有prototype属性(显式原型)(仅限函数)

代码简单分析

var one = {x: 1};
var two = new Object();
one.__proto__ === Object.prototype // true
two.__proto__ === Object.prototype // true
one.toString === one.__proto__.toString // true

我们知道JS是单继承的,Object.prototype是原型链的顶端,所有对象从它继承了包括toString等等方法和属性。

这里有个鸡和蛋的问题

Object本身既然是构造函数,继承了Function.prototype;Function也是对象,继承了Object.prototype

// 控制台输出
Object instanceof Function // true
Function instanceof Object // true

Function本身就是函数,Function.__proto__是标准的内置对象Function.prototype
Function.prototype.__proto__是标准的内置对象Object.prototype

  • 1、Function.prototype和Function.__proto__都指向Function.prototype,这就是鸡和蛋的问题怎么出现的
  • 2、Object.prototype.__proto__ === null,说明原型链到Object.prototype终止,也就是原型链的顶端

只要是对象,就会有原型,就会有__proto__

任意函数(因为函数本身也是对象),就是说 function xxx() {} 的原型(通过__proto__往上找)就是 Function.prototype (还没完),而普通对象(比如{},或者xxx.prototype)的原型(通过__proto__往上找)就是 Object.prototype,但是 Function.prototype 也有__proto__ , 并且 proto 还是指向 Object.prototype,因为 Object.prototype 才是所有人的爸爸

总结

1、所有的函数都同时拥有__proto__和protytpe属性 函数的__proto__指向自己的函数实现 函数的protytpe是一个对象 所以函数的prototype也有__proto__属性 指向Object.prototype
2、所有的JS对象都有一个prototype属性,指向它的原型对象。当试图访问一个对象的属性时,如果没有在该对象上找到,它还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾Object.prototype终止

题目

题目来源网络,看了上面分析,下面的题目能如若能分析出来,差不多对原型链有了基础掌握,剩下的在实际工作去挖掘它更深的意义

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);
console.log(b.m);

console.log(c.n);
console.log(c.m);

2、请写出下面编程的输出结果是什么?

var F = function() {};
Object.prototype.a = function() {
  console.log('a');
};
Function.prototype.b = function() {
  console.log('b');
}
var f = new F();

f.a();
console.log(f.b);

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

3、请看下面 p.__proto__等于什么?
4、请看下面 Person.__proto__等于什么?

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

5、请写出下面编程的输出结果是什么?

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

console.log(foo.a);
console.log(foo.b);

console.log(F.a);
console.log(F.b);

答案

题目 1 答案:

b.n -> 1
b.m -> undefined;

c.n -> 2;
c.m -> 3;

题目 2 答案:

f.a() -> a
f.b -> f.b is not a function

F.a() -> a
F.b() -> b

题目 3 答案

Person.prototype

题目 4 答案

Function.prototype

题目 5 答案

foo.a => value a
foo.b => undefined
F.a => value a
F.b => value b

参考文章

Javascript 面向对象编程
JS 原型与原型链
JavaScript 世界万物诞生记

关于我

https://www.vipbic.com/.png

阅读 580

推荐阅读
vipbic
用户专栏

vipbic是一个关注前端开发、网址导航、学习视屏免费下载、HTML5、CSS3、JavaScript、PHP的前端杨航开发...

35 人关注
42 篇文章
专栏主页