前端面试经常会问关于原型链的知识,今天我总结了一下关于原型链的内容,希望对广大小白一点点参考~
什么是原型?
在 js 中,对象都有 __proto__ 属性, 就是指这个对象的原型,如果构造函数 A 实例化一个对象 B,那么 A.prototype 就是 B 的原型。也就是:
function A(){} var B = new A(); B.__proto__ == A.prototype
什么是原型链?
介绍完原型,那么就必须说原型链了。
刚才提到,每个对象都有 __proto__属性,指向其构造函数的 prototype, 而 prototype 的值也是一个对象啊,所以就形成一条链,称为原型链。
举个例子:
cat 的原型链
我们创建一个叫做 Animal 的类, 并实例化一个对象 cat,我们来一点一点探索 cat 所处的原型链。
function Animal( name){ this.name = name; } var cat = new Animal("cat");
cat 由 Animal 实例化而来,那么就之前的说法,cat 的 __proto__ 指向 Animal 的 prototype:
的确如此!
接下来考虑到 Animal 的 prototype 也是一个对象,也有原型 ,那么 Animal.prototype 的 __proto__ 有指向什么呢?
我们分析到 Animal 的 prototype 是一个对象, 那么应该由 Object 构造,这么说,Animal.prototype.__proto__ 应该指向 Object.prototype 。
Object.prototype 也是一个对象啊,那么它的原型又是什么?
原型链的定义中提到,原型链的终点指向 null 。所以, Object.prototype.__proto__ 应该指向 null。
小结
实例化 cat 有以下关系:
1. cat 由 Animal 构造,所以有:cat.__proto__ == Animal.prototype;
2. Animal.prototype是一个对象,由 Object 构造,所以有:Animal.prototype.__proto__ == Object.prototype;
3. 原型链的终点指向 null,所以有:Object.prototype.__proto__ == null;
也就是:
cat.__proto__.__proto__.__proto__ == null;
图示:
这就是 cat 的原型链了,我们知道了什么是原型链,那么原型链有什么用?
原型链的作用
当我们用一个构造函数实例化很多不同的对象,而又希望给这些对象绑定相同的方法,就可以绑定到它们的构造函数上去。
举个例子:
我们想让所有的字符串都拥有一个去掉空格的方法,调用这个方法,就能去掉字符串中的所有空格。我们只需要给 String.prototype 绑定一个方法:
String.prototype.trim = function(){ return this.replace(/s+/g,""); }; var str = "This is a good day!"; console.log(str.trim());
//打印出 Thisisagoodday!
原型链的属性查找规则
当从对象搜寻一个属性或者方法的时候,会遵循以下规则:
1. 先从本身拥有的属性或方法查找,如果对象本身有,那就直接用自己的属性或者方法;
function Animal( name){ this.name = name; this.say = function (){ console.log("hello cat!"); } } var cat = new Animal("cat"); cat.say = function (){ console.log("cat hello!"); } cat.say(); //打印出 cat hello!
2. 当本身找不到这个属性或者方法的时候,就会沿着原型链找,使用原型链上的方法或者属性;
function Animal( name){ this.name = name; this.say = function (){ console.log("hello cat!"); } } var cat = new Animal("cat"); cat.say(); //打印出 hello cat!
3. 原型链也找不到,那么找不到的属性返回 undefined,找不到的方法会报错,提示不是一个 function。
console.log(cat.sayHello()); // 报错:Uncaught TypeError: cat.sayHello is not a function console.log(cat.age); //undefined
特殊的:
没有原型属性的对象
通过 Object.create(null)生成没有原型的对象。
后记
这是我对原型链知识的一点理解和看法,如有错误的理解或表述,欢迎大家指出,接下来我会着重探究几个特殊的对象(Object、Function等)的原型。请大家多多支持!
如需转载,请指明出处,素质转载,谢谢。