原型
在写这篇文章之前也看了很多相关的内容,发现很多的都是绕来绕去,然后写一堆判断,问你看没看懂,我不知道各位看官懂没懂,反正我是不怎么懂。 我这里简单说下自己的理解:
- 原型就是一个普通对象,Js赋予了它特殊的意义,它可以被分享给自己的实例对象。
- 通过__prototype__进行实例与构造函数的原型对象进行连接,进行属性的查找,这就是原型链查找的过程
普通对象和函数对象
Js中的对象分为普通对象和函数对象,Object,和Function是Js自带的函数对象
var o1 = {};
var o2 =new Object();
var o3 = new f1();
function f1(){};
var f2 = function(){};
var f3 = new Function('str','console.log(str)');
console.log(typeof Object); //function
console.log(typeof Function); //function
console.log(typeof f1); //function
console.log(typeof f2); //function
console.log(typeof f3); //function
console.log(typeof o1); //object
console.log(typeof o2); //object
console.log(typeof o3); //object
凡是通过 new Function() 创建的对象都是函数对象,其他都是普通对象
原型对象
所有的函数对象都有个prototype属性
function Person() {};
Person.prototype.name = 'lili';
Person.prototype.age = 28;
以上这些属性都是定义在Persion的原型上
原型的作用
function Person() {};
Person.prototype.name = 'lili';
Person.prototype.age = 28;
const p1 = new Person()
const p2 = new Person()
console.log('p1', p1.name) //lili
console.log('p2', p2.name) //lili
从上面可以看出p1,p2两个实例共享了函数对象的原型,所以原型的作用主要用于继承
原型链
上面的说到了继承,但是实例是怎么找到函数对象的原型属性呢?这就需要原型链了 这里我们打印一下上面的实例p1

- 实例p1上有个属性__proto__,它与函数对象Person的prototype一致
- 得出结论1: p1.proto = Person.prototype
- proto他也是一个普通的对象,所以它也有__proto__属性,这里可以看到它是指向Object对象的原型
- 得出结论2: Person.prototype.__proto__ === Object.prototype
- 而Object.prototype.proto === null 查找到此结束
所以原型链的整体逻辑如下:
- 先从实例自身的属性查找
- 找不到再从实例的__prototype__,__prototype__实际就是构造函数的prototype
- 如果构造函数的prototype里面也没有,则从构造函数的prototype的__prototype__查找
- 一直查找到__prototype__ 为null为止
Js内置的构造器
var obj = {name: 'jack'}
var arr = [1,2,3]
var reg = /hello/g
var date = new Date
var err = new Error('exception')
console.log(obj.__proto__ === Object.prototype) // true
console.log(arr.__proto__ === Array.prototype) // true
console.log(reg.__proto__ === RegExp.prototype) // true
console.log(date.__proto__ === Date.prototype) // true
console.log(err.__proto__ === Error.prototype) // true
所以这些对象都具备很多内置的方法