这篇文章将详细讲述javascript中的继承与原型链,文字和代码全面解析,具有一定的参考价值,需要的小伙伴可以参考一下,希望可以帮助到你。
javascript里的一切几乎都是对象,每一个对象都有一个链接到其他对象的内部属性,我们称之为prototype (原型)。原型对象自己也有自己的原型对象,以此类推,这时候原型链就出来了。如果你追踪原型链,你最终会到达原型为 null的内核 object,这是原型链的终点。
原型链的作用是什么呢?当我们访问一个对象并不拥有的属性时,javascript会检索原型链,直到它找到了这个属性或是原型链的终点。这个行为保证了我们可以去创建“类”与实现继承。
如果还不理解的话,没有关系,让我们在实践中理解。现在看一个javascript最简单的例子:一个在方法对象中创建的“类”
function animal() {}var animal = new animal();
有两种方法可以让我们给这个animal类添加属性:设置实例的属性或者添加animal 原型。
function animal(name) { // instance properties can be set on each instance of the class this.name = name;}// prototype properties are shared across all instances of the class. however, they can still be overwritten on a per-instance basis with the `this` keyword.animal.prototype.speak = function() { console.log("my name is " + this.name);};var animal = new animal('monty');animal.speak(); // my name is monty
当查看控制台animal 对象的结构就会变得很清晰。我们可以看到 name属性是属于对象本身,而speak 则是属于animal 原型的。
现在请看一下我们是如何扩展animal 类来创建一个cat 类:
function cat(name) { animal.call(this, name);}cat.prototype = new animal();var cat = new cat('monty');cat.speak(); // my name is monty
我们所做的设置cat的原型为一个animal 实例,所以cat 会继承animal的所有属性。同样的我们使用animal.call 使用来继承animal 的构造函数。call 是一个特殊的函数,它允许我们调用函数且在函数中指定this的值。所以当this.name在animal 的构造函数中,cat的名称就被设定了,而不是animal的。
让我们一起看一下cat 对象:
如我们所期望的一样,cat 对象有了自己的name 实例属性。当我们查看对象的原型我们会看到它同样继承了animal 的name 实例属性,speak 原型属性也是如此。这就是原型链的样子,当访问 cat.name,javascript就会查找name实例属性,不会往下去搜索原型链。不管怎样,当我们去访问 cat.speak,javascript就必须往下去搜索原型链直到它发现从animal现继承的speak 属性。
以上就是深入理解javascript中的继承与原型链的详细内容。