JavaScript面向对象核心知识与概念归纳整理(3)

function A(){ this.name='lala'; } var a=new A(); console.log(A.prototype) //输出:Object {} console.log(A.__proto__) //输出:function () {} console.log(Object.getPrototypeOf(A)) //输出:function () {}

函数的的prototype属性只有在当作构造函数创建的时候,把自身的prototype属性值赋给对象的原型。而实际上,作为函数本身,它的原型应该是function对象,然后function对象的原型才是Object。

总之,建议使用ES6推荐的查看原型和设置原型的方法。

5.3 原型的用法

其实原型和类的继承的用法是一致的:当你想用某个对象的属性时,将当前对象的原型指向该对象,你就拥有了该对象的使用权了。

function A(){ this.name='world '; } function B(){ this.bb="hello" } var a=new A(); var b=new B(); //将b设置为a的原型,此处有一个问题,即a的constructor也指向了B构造函数,可能需要纠正 Object.setPrototypeOf(a,b); a.constructor=A; console.log(a.bb); //hello

如果使用ES6来做的话则简单许多,甚至不涉及到prototype这个属性

class B{ constructor(){ this.bb='hello' } } class A extends B{ constructor(){ super(); this.name='world'; } } var a=new A(); console.log(a.bb+" "+a.name); //hello world console.log(typeof(A)) //"function"

怎么样?是不是已经完全看不到原型的影子了?活脱脱就是类继承,但是你也看得到实际上类A 的类型是function,所以说,本质上class在JS中是一种语法糖,JS继承的本质依然是原型,不过,ES6引入class,extends 来掩盖原型的概念也是一个很友好的举动,对于长期学习那些类继承为基础的面对对象编程语言的程序员而言。

我的建议是,尽可能理解原型,尽可能用class这种语法糖。

好了,问自己两个问题:

为什么要使用原型?——提高函数的复用性。

为什么属性不放在原型上而方法要放在原型上?

利用对象的动态特性:构造函数.prototype.xxxx = vvv

利用直接替换

Student.prototype = { sayHello : function(){}, study : function(){} };

5.4 原型链

什么是原型链?
凡是对象就有原型,那么原型又是对象,因此凡是给定一个对象,那么就可以找到他的原型,原型还有原型,那么如此下去,就构成一个对象的序列,称该结构为原型链。

每个实例对象都有一个__proto_属性,该属性指向它原型对象,这个实例对象 的构造函数有一个原型属性 prototype,与实例的__proto__属性指向同一个对象。当一个对象在查找一个属性的时, 自身没有就会根据__proto__ 向它的原型进行查找,如果都没有,则向它的原型的原型继续查找,直到查到 Object.prototype._proto_为 null,这样也就形成了原型链。

这个概念其实也变得比较简单,可以类比类的继承链条,即每个对象的原型往上追溯,一直到Object为止,这组成了一个链条,将其中的对象串联起来,当查找当前对象的属性时,如果没找到,就会沿着这个链条去查找,一直到Object,如果还没发现,就会报undefined。

原型链的结构
凡是使用构造函数,创建出对象,并且没有利用赋值的方式修改原型,就说该对象保留默认的原型链。
默认原型链结构是什么样子呢?

function Person(){} var p = new Person(); //p 具有默认的原型链

默认的原型链结构就是:当前对象 -> 构造函数.prototype -> Object.prototype -> null

在实现继承的时候,有时候会利用替换原型链结构的方式实现原型继承,那么原型链结构就会发生改变

function DunizbCollection(){} DunizbCollection.prototype = []; var arr = new DunizbCollection();

此时arr对象的原型链结构被指向了数组对象的原型链结构了:arr -> [] -> Array.prototype -> Object.prototype -> null

用图形表示对象的原型链结构
以如下代码为例绘制原型链结构

function Person(){} var p = new Person();

原型链结构图为:

JavaScript面向对象核心知识与概念归纳整理

使用原型需要注意两点:

原型继承链条不要太长,否则会出现效率问题。

指定原型时,注意constructor也会改变。

六、继承

实现继承有两种常见方式:

6.1 混合式继承

最简单的继承就是将别的对象的属性强加到我身上,那么我就有这个成员了。
混合式继承的简单描述:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ae0a310d791581ed9286b871cb4f5bd1.html