美文网首页
js原型,原型链

js原型,原型链

作者: 宁骥 | 来源:发表于2017-09-14 13:15 被阅读0次

    原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性。

    在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个”[[Prototype]]”内部属性,这个属性所对应的就是该对象的原型。

    在JavaScript中,每个函数 都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例(也就是设置 实例的`__proto__`属性),也就是说,所有实例的原型引用的是函数的prototype属性。(****`只有函数对象才会有这个属性!`****)

    new 的过程分为三步

    var p = new Person('张三',20);

    1. var p={}; 初始化一个对象p。

    2. p._proto_=Person.prototype;,将对象p的 __proto__ 属性设置为 Person.prototype

    3. Person.call(p,”张三”,20);调用构造函数Person来初始化p。关于call/apply使用

    原型链

    因为每个对象和原型都有原型,对象的原型指向原型对象,

    而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。

    一、属性查找

    当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶部(也就是 Object.prototype),如果仍然没有找到指定的属性,就会返回 undefined。

    function Person(name, age){

    this.name = name;

    this.age = age;

    }

    Person.prototype.MaxNumber = 9999;

    Person.__proto__.MinNumber = -9999;

    var will = new Person("Will", 28);

    console.log(will.MaxNumber); // 9999

    console.log(will.MinNumber); // undefined

    在这个例子中分别给”Person.prototype “和” Person.proto”这两个原型对象添加了”MaxNumber “和”MinNumber”属性,这里就需要弄清”prototype”和”proto”的区别了。

    “Person.prototype “对应的就是Person构造出来所有实例的原型,也就是说”Person.prototype “属于这些实例原型链的一部分,所以当这些实例进行属性查找时候,就会引用到”Person.prototype “中的属性。

    当使用这种方式创建一个对象的时候,原型链就变成下图了. July对象的原型是”Object.prototype”也就是说对象的构建方式会影响原型链的形式。

    {}对象原型链结构图

    综图所述

    1. 所有的对象都有__proto__属性,该属性对应该对象的原型.

    2. 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对3. 象的_proto_属性.

    4. 所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数.

    5. 函数对象和原型对象通过prototype和constructor属性进行相互关联.

    另一种解释:

    对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,其实市面上已经有非常多的文章在尝试说清楚,有一张所谓很经典的图,上面画了各种线条,一会连接这个一会连接那个,说实话我自己看得就非常头晕,更谈不上完全理解了。所以我自己也想尝试一下,看看能不能把原型中的重要知识点拆分出来,用最简单的图表形式说清楚。

    我们知道原型是一个对象,其他对象可以通过它实现属性继承。但是尼玛除了prototype,又有一个__proto__是用来干嘛的?长那么像,让人怎么区分呢?它们都指向谁,那么混乱怎么记啊?原型链又是什么鬼?相信不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,下面用三张简单的图,配合一些示例代码来理解一下。

    一、prototype和__proto__的区别

    vara ={};

    console.log(a.prototype);//undefinedconsole.log(a.__proto__);//Object {}varb =function(){}

    console.log(b.prototype);//b {}console.log(b.__proto__);//function() {}

    /*1、字面量方式*/vara ={};

    console.log(a.__proto__);//Object {}console.log(a.__proto__=== a.constructor.prototype);//true/*2、构造器方式*/varA =function(){};vara =newA();

    console.log(a.__proto__);//A {}console.log(a.__proto__=== a.constructor.prototype);//true/*3、Object.create()方式*/vara1 = {a:1}vara2 =Object.create(a1);

    console.log(a2.__proto__);//Object {a: 1}console.log(a.__proto__=== a.constructor.prototype);//false(此处即为图1中的例外情况)

    varA =function(){};vara =newA();

    console.log(a.__proto__);//A {}(即构造器function A 的原型对象)console.log(a.__proto__.__proto__);//Object {}(即构造器function Object 的原型对象)console.log(a.__proto__.__proto__.__proto__);//null

    参考:http://www.cnblogs.com/shuiyi/p/5305435.html

    相关文章

      网友评论

          本文标题:js原型,原型链

          本文链接:https://www.haomeiwen.com/subject/ppzrsxtx.html