关于原型链的心得体会

    xiaoxiao2025-07-16  6

    附上别人总结的例子,方便查阅:JS原型链简单图解

    个人笔记:记住下面的图。

    实例对象的隐式指向(__proto__)的原型等于构造器的显式指向的(prototype)原型。

    比如:

    function Foo(){}

    var f1 = new Foo();

    console.log(f1.__proto__ === Foo.prototype); // true

    由图中可以得出一下结论

    Object.__proto__.__proto__ === Object.prototype    // true

    Object.__proto__ === Function.prototype  // true

    之后所有的讲解围绕这幅图展开。(图中__proto__代表隐式指向,prototype代表显式指向)

                                              原型链示意图1

    Object.__proto__即为Function.prototype,控制台显示为

           为什么呢?Object也是一个函数,比如函数function Foo(){}可以看成var Foo = new Function();

           那么function Object(){...}也可以看成var Object = new Function();所以Object可以看成是Function的实例对象,实例对象的隐式指向(__proto__)的原型等于构造器的显式指向的(prototype)原型,那么Object.__proto__就是等于Function.prototype。所以js说万物皆对象不是没有道理的。

           总结:一般看到控制台这样的[native code],马上想到Function的显式指向的原型对象,再结合原型链示意图1思考。

    Object.__proto__.__proto__即为Object.prototype,控制台显示如下:

           为什么Object.__proto__.__proto__即为Object.prototype呢?由上一个问题已经得出Object.__proto__即为Function.prototype(Function显式指向的原型对象,是一个对象),由实例对象的隐式指向(__proto__)的原型等于构造器的显式指向的(prototype)原型,得出Function.prototype.__proto__(实例对象的隐式指向的原型)等于Object.prototype(构造器的显式指向的原型),所以Object.__proto__.__proto__等于Object.prototype。

     

    A instanceof B

    只要A的隐式原型链(__proto__)能够追溯到B的显式指向的原型对象(prototype),就返回true,否则为false。

    function fn(){} var obj = {} console.log(fn instanceof Function)//true /* 把function fn(){}看成var fn = new Function(); 那么fn.__proto__就是Function.prototype,fn的隐式原型链能到达Function的显式指向的原型对象,为true */ console.log(obj instanceof Object)//true /* obj就是一个空的Object对象,记住,是对象,和new Object一样,对象的隐式原型obj.__proto__就是Object的显式原型, 已经到达,为true,该情况比较特殊,得记住。 */ console.log(fn instanceof Object)//true /* 把function fn(){}看成var fn = new Function();之后可以得出,fn.__proto__是Function的原型 (即Function.prototype),再接着fn.__proto__.proto__就是Object的原型(Object.prototype),已到达,为true,具体可见原型链示意图1 */ console.log(obj instanceof Function)//false /* obj是个空对象,obj.__proto__就是Object的原型对象(Object.prototype),obj.__proto__.proto__ 就是null,终止,没有到达Function.prototype,所以false */

    如果尝试访问对象的显式指向(prorotype)的原型对象呢?有吗?对象没定义这个属性之前都是undefined,而__proto__是隐式已经定义好的。 

     

    接下来来看看一些例子:

    /* 测试题1 */ function A() { } A.prototype.n = 1; var b = new A(); A.prototype = { n: 2, m: 3 }; var c = new A(); console.log(b.n, b.m, c.n, c.m);

    控制台执行结果是:

           1 undefined 2 3

    解释:

           声明函数时创建的function对象A(),同时创建原型对象用A.prototype显式指向它,这个原型对象再隐式指向Object的显式原型对象(Object.prototype),具体见原型链示意图1。

           接着这个A()的显式指向的原型对象里面添加一个属性n为1。

           声明b指向实例对象A,这个对象b的__proto__就是A.prototype(A的显式指向的原型对象),见原型链示意图1

           现在要开始改变了,A()的显式指向的原型对象变了!!!意味着这个工厂以后创建对象的原型对象都变了,但是原来的原型对象还有东西去指着它的,那就是刚刚的b,b对象的隐式指向的原型对象被A()抛弃了,里面还有刚刚添加的n为1呢。

           新工厂造新对象c,隐式指向的原型对象就是新的{n:2, m:3}

           所以最后控制台打印的是1 undefined 2 3

     如果被function A() 抛弃的原型对象没有被b隐式指向呢??

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

    那么答案就是2 3 2 3

     

     

    来看看测试题2

    /* 测试题2 */ function F (){} Object.prototype.a = function(){ console.log('a()') } Function.prototype.b = function(){ console.log('b()') } // 下面操作均可以看原型链示意图1得出解释 var f = new F() f.a() // 打印a() // f.b() // 会报错,b not a function F.a() // 打印a() F.b() // 打印b()

    ==============Talk is cheap, show me the code================

    最新回复(0)