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

简介: 我对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


相关文章
|
2月前
|
JavaScript 前端开发 开发者
理解JavaScript中的原型链:基础与实践
【10月更文挑战第8天】理解JavaScript中的原型链:基础与实践
|
4月前
|
JavaScript 前端开发
如何在JavaScript中实现基于原型的继承机制
【8月更文挑战第14天】如何在JavaScript中实现基于原型的继承机制
31 0
|
29天前
|
JavaScript 前端开发
JavaScript 原型链的实现原理是什么?
JavaScript 原型链的实现原理是通过构造函数的`prototype`属性、对象的`__proto__`属性以及属性查找机制等相互配合,构建了一个从对象到`Object.prototype`的链式结构,实现了对象之间的继承、属性共享和动态扩展等功能,为 JavaScript 的面向对象编程提供了强大的支持。
|
29天前
|
JavaScript 前端开发
原型链在 JavaScript 中的作用是什么?
原型链是 JavaScript 中实现面向对象编程的重要机制之一,它为代码的组织、复用、扩展和多态性提供了强大的支持,使得 JavaScript 能够以简洁而灵活的方式构建复杂的应用程序。深入理解和熟练运用原型链,对于提升 JavaScript 编程能力和开发高质量的应用具有重要意义。
|
1月前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
2月前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
32 1
|
2月前
|
JavaScript 前端开发 开发者
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
27 0
|
2月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
35 0
|
2月前
|
JavaScript 前端开发 安全
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
29 0
|
3月前
|
JSON JavaScript 前端开发
js原型继承|26
js原型继承|26