标签:
javascript是一门面向对象的语言,但它却没有像其他面向对象的语言(如java,C++)有类的概念,也没有基于类的继承体系。但是它有自己独特的继承方式,那就是基于原型和原型链的继承。
当我们创建一个对象时,每个对象在生成之后都有一个隐式的属性__proto__(非规范,暂且这么叫吧),该属性指向该实例的原型对象,并共享其原型对象上的属性和方法。
下面分析下不同创建对象的方式所对应的__proto__属性指向的不同。
1.用对象字面量创建对象。
var a={x:1}; console.log(a.__proto__);//{}
上面的代码表明a对象的__proto__属性为一个空对象,是否意味着用对象字面量创建的对象一开始的__proto__属性都是指向的一个空对象呢?我们看看下面代码。
var a={x:1}; Object.prototype.y=1; console.log(a.__proto__);//{y:1} console.log(a.y);//1
从以上代码很明显可以看出,a的__proto__指向的是Object的prototype对象,并且a继承了Object原型对象上的属性。所以用对象字面量创建的对象的__proto__属性指向的是Object的原型对象。
2.用构造函数方法创建对象。
function foo(name){ this.name = name; } b=new foo("b"); foo.prototype.sayName=function(){ console.log(this.name); } console.log(b.__proto__===foo.prototype);//true cosnsole.log(b.sayName());// b
通过构造函数创建的对象b的__proto__指向foo.prototype。
以上分析了不同方式创建对象的原型对象的不同,接下来说一下原型链
从上面的分析我们知道,每个对象都有一个__proto__属性指向其原型对象,而原型对象本身也是一个对象,它也有一个__proto__属性指向其原型对象,如此反复,形成链式结构。我们学过链表等链式结构,此结构必须有一个终点,不然就会构成死链。那原型链的终点在哪呢?
function foo(name){ this.name = name; } b=new foo("b"); foo.prototype.sayName=function(){ console.log(this.name); } console.log(foo.prototype.__proto__===Object.prototype)//true console.log(foo.prototype.__proto__.__proto__)//null console.log(foo.prototype.__proto__.__proto__.__proto__)//报错,null没有__proto__属性
foo.prototype对象的__proto__指向的是Object.prototype,而Object.prototype.__proto__属性值为null,不再有__proto__属性,也就是说原型链就终止于此了。
以此文记录下自己对原型和原型链的认识,欢迎批评指正。
标签:
原文地址:http://www.cnblogs.com/RealRaul/p/4639309.html