# prototype **Repository Path**: pipepandafeng/prototype ## Basic Information - **Project Name**: prototype - **Description**: js中原型,原型链理解。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-10-11 - **Last Updated**: 2022-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 原型 prototype 理解原型,原型链。 ## 基础概念 1. 对应名称 * `prototype` 原型 * `__proto__` 原型链(链接点) 2. 从属关系 * `prototype` 函数的一个属性 * `__proto__` 对象的一个属性。每个对象的属性。是一个指向构造函数原型的属性(对象的__proto__保存着该对象构造函数的prototype) ## 原型链和原型的关系 1. 声明一个函数`Test` ```js function Test() {} ``` 2. 打印该函数原型 ```js console.log(Test.prototype); ``` ![RUNOOB 图标](./img/1.png) 3. 构造函数的实例 ```js var t = new Test(); console.log(t.__proto__) ``` ![RUNOOB 图标](./img/1.png) 故: `t.__proto__ === Test.prototype` 。 ![RUNOOB 图标](./img/2.png) > 结论:实例可通过链接点找到创建该实例的原型对象。即 `t.__proto__ === Test.prototype` 5. 函数实际是由对象创建的 ```js /* 原型对象也是一个对象。故而Test.prototype也有一个属性为__proto__ */ console.log(Test.prototype.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__); // null ``` ## 深入认识原型,原型链的继承关系( `js` 通过采用原型链来实现继承关系) * 改造函数`Test` ```js function Test() { this.a = 'a' } Test.prototype.a = 'a1' Test.prototype.b = 'b' Object.prototype.c = "c"; var t = new Test(); console.log(t.a); // a console.log(t.b); // b console.log(t.c); // c ``` ``` * test:{ * a:'a', * __proto__:Test.prototype={ * b:'b', * __proto__:Object.prototype={ * c:'c', * x __proto__ * } * } * } ``` > 结论:原型链即为以一个对象为基准 `t` ,以 `__proto__` 为链接的一个链条。 > 注意:如果对象上找得到属性,就不会去原型链上找。 ## `Funcion` 和 `Object` 的特殊性 Test函数实际是由New Funcion构造出来的,故Test也应该有 `__proto__` 属性。我们打印可看到,Test的 `__proto__` 属性实际上指向了Function的 `prototype` (原型对象) ```js /* const Test= new Function() */ console.log(Test.__proto__ === Function.prototype) // true ``` > 结论1: `Function.__proto__ = Function.prototype` ```js const obj = {} const obj = new Object() // Object实际是一个函数 ``` 对象obj实际是由一个构造函数Object来创建的,既然 `Object` 是一个函数,那么 `Object` 的 `__proto__` 是肯定指向函数的原型,通过打印我们也证实了下面结论。 > 结论2: `Object.__proto__ = Function.prototype` 结合 `结论1` 和 `结论2` ,我们得出 `结论三` > 结论3: `Object.__proto__ = Function.__proto__` > 结论4: 万物皆函数 ## 构造器 `constructor` 与实例的关系和特性 ```js console.log(Test.prototype.constructor == Test) // true console.log(t.constructor == Test) // true ``` > 结论1:实例 `t` 的 `constructor` 实际是从原型链上继承下来的。 > 结论2:实例 `t` 的 `constructor` 执行该构造函数本身。 > 结论3:构造函数的原型 `prototype` 的 `constructor` 又指向回到了自己。 > 结论4: `constructor` 属性可修改,主要作用是正确显示构造器是谁。 ```js function Test() {} var test = new Test() test.constructor = Test1; console.log(test) ``` ![修改构造器](./img/3.png) ## 参考文献 [快速搞懂原型、原型链 - bilibili](https://www.bilibili.com/video/BV1ci4y157Ci?p=4)