js对象,函数,原型,原型链

对象 Object,函数 Function, 原型 prototype,原型链__proto__;如何才能掌握这四者的关系呢。

一 对象。

创建对象的三种方式。

1 var obj1 = new Object();

2 var obj2 = {};

3  但想抽取公共的属性,做一个模板。 通过构造函数创建对象。

function Star(){

this.uname= uname;

this.age = age;

this.sing = function(){

console.log('sing')}

}

var caomei = new Star('caomei',18);

var dashu = new Star('dashu',18);

构造函数1名称需要大写。2 不需要返回。

对象new的过程。

new 在执行的时候干了4件事。

1 内存中创建一个空对象。

2 让this指向这个空对象。

3 构造桉树里面的代码,给新对象添加属性和方法。

4 返回这个新对象。

  • 创建一个全新的对象。
  • 这个新对象的原型(Object.getPrototypeOf(target))指向构造函数的prototype
  • 该函数的this会绑定在新创建的对象上。
  • 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。
  • 我们称这个新对象为构造函数的实例。

对象的两个成员。

1 实例成员。构造函数内部。通过内部this添加的成员。uname age sing都是实例成员。

实例成员只能通过实例化的对象来访。不能通过构造函数来访问实例成员!

2 静态成员 在构造函数本身上添加的成员 sex就是构造成员。

Star.sex = ‘man’;

静态成员只能通过构造函数访问。Star.sex;

二 构造函数的原型属性:prototype

为什么要有prototype?

两个实例对象,开辟两个内存空间,存放函数。浪费内存问题。

caomei.sing() !== dashu.sing()

 如何节省空间呢?

构造函数 通过原型分配的的函数 是所有对象所共享的!!!

每一个构造函数都有一个 prototpe属性! 每一个构造函数拥有prototype的属性和方法。

作用:我们可以吧那些不变的方法,直接定义在prototype对象上。

Star.prototype.sing = function(){ console.log('sing')};

var ldh = new Star();

var zxy  = new Star();

ldh.sing();

三 对象的原型。以及原型链。__proto__。

问题 :ldh对象 并没有 sing方法,哪里来的?

虽然对象ldh身上没有sing,但是对象有__proto__,它指向我们构造函数的原型对象。

Star0是没有sing方法。Star1也没有sing方法,但是Star1的proto是有sing方法的。

本质:__proto__是用来寻找构造函数prototype原型的,这样就可以继承了。

对象的查找规则:(先看自己是否有钱,没有钱找父母要。)

 1先看对象身上是否有sing方法。

 2 在根据__proto__原型链,去构造函数原型prototype身上查找sing。

4 constructor构造函数。

构造函数prototype原型对象有constructor属性。

这个属性可以指回构造函数的本身。

constructor作用:用于记录该对象引用的哪个构造函数,可以让原型对象重新指向原来的构造函数。

 Object.prototype = {sing:function}直接修改prototype属性。会覆盖掉之前的。

 Object.prototype.sing; prototype添加属性。

上面讲了对象,原型,原型链,原型属性的constructor属性。我们这次把原型链讲懂。

对象Object是哪里来的 。当然是object构造函数构造出来的。

function Object()当然有prototype属性。Object.prototype属性的proto原型是谁呢?当然是null。

function Object()的proto属性指向的是谁呢?  指向的是function.prototype;

function Function() 当然也有prototype属性。 Fcuntion.prototype的proto原型是谁?是Object.prototype。

function Function()的proto属性指向的是谁?  很诧异,是Fcuntion.prototyp。这个是它的底层实现。这个就是最诡异的。一般都是一个三角关系。这个是一个平行关系 。

注意四个对象的__proto__都指向哪里?

两个函数的原型__proto__都是指向 Fcuntion prototype。结论:也就是说构造函数的原型都是Fcuntion prototype。

但是 Object.prototype的 proto指向的null。

但是Function.prototype,和其他构造函数的prototype是指向 Object.prototype。

结论:

当fcuntion Foo(){}的时候。

Foo.__proto__找的是function.prototype。

Foo.prototype找的是object.protptype;

当var foo1 = new Foo的时候;

foo.__proto__找的是Foo.prototype;

在总结一下:

所有构造函数都必须有个prototype属性。这个属性有个constructor 指回去。

找的是翻译成就是原型链。

构造函数的函数(Fun) 找的是 Fcuntion.prototype(它就是用来生产构造函数的)。

构造函数的函数属性(Fun.prototype) 找的是Object.prototype(它是用来生产构造函数的prototype属性)。

构造函数的对象(fun1,fun1) 找的是 构造函数的函数属性Function.prototype(它是用来生产构造函数的对象的。)。

6 js查找机制:(按照原型链的查找机制)

1 再查找对象。2找对象的构造函数。3找对象的构造函数的构造函数。4 在没有了。就是null。

如果第一次查找到成员,那么不在继续查找对象,直接结束。也可以称为就近原则。

在对象自身查找的方法:

object.hasOwnProperty('a');

'a' in object

ES6以后都是类class,但是proto是自己造轮子,和看源码必备的。

几个个博客写的很好:

掘金:

https://juejin.cn/post/6844903989088092174

https://juejin.cn/post/6844904097166917639

https://juejin.cn/post/6844903585336016903

https://juejin.cn/post/6844903924307230727#heading-1

https://juejin.cn/post/6844903806694588424

https://juejin.cn/post/6902282491030470663

知乎:

https://zhuanlan.zhihu.com/p/294808520

csdn:

https://blog.csdn.net/qq_34803821/article/details/85003256

https://blog.csdn.net/qq_34803821/article/details/85003441

https://blog.csdn.net/qq_34803821/article/details/85003539 

几个视频也很不错

攻克原型原型链:

https://www.bilibili.com/video/BV1ci4y157Ci?p=6   

https://www.bilibili.com/video/BV1KJ411x7X7?p=30   (后盾人)

综合知识:

https://www.bilibili.com/video/BV1KJ411x7X7?p=30  (pink老师)

面试考点:

https://www.bilibili.com/video/BV1ti4y187hg/?spm_id_from=333.788.recommend_more_video.0

原文地址:https://www.cnblogs.com/hacker-caomei/p/14145601.html