[url=http://lixh1986.iteye.com/blog/2332467]前文[/url]讲到“属性继承”所存在的问题:重复。本文专注于“原型(prototype)继承”。
[size=medium][b]背景知识:[/b][/size][url=http://lixh1986.iteye.com/blog/1896682][size=medium][b]什么是函数的 prototype 属性?[/b][/size][/url]
函数在定义(创建)时,会自动被添加一个 prototype 属性。
1、prototype 属性是一个空对象 {},然后被添加了一个 constructor 属性,指向函数自身。
2、prototype 属性被函数(使用 new 操作符生成)的实例共享。
3、在访问函数实例的某个属性时,如果该属性不存在,则向其 __proto__ 属性中寻找,如果仍然不存在则向其 __proto__ 属性的 __proto__属性中寻找,直至根。
[color=gray]再补充一句:constructor 的意义?
由于
1) constructor 属性,指向函数自身。
2) prototype 属性被函数的实例共享。
3) constructor 属性是 prototype 的一部分。
所以函数的各个实例便可以通过 constructor 属性确定,它们来自于同一个构造函数。[/color]
[size=medium][b]一、继承其它函数的 prototype 属性[/b][/size]
函数 A(即将要被创建)的 prototype 属性是空的,未被使用的。
函数 B 的 prototype 属性将被函数 A 继承。
有以下方案:
[b]1、直接引用函数 B 的 prototype 对象作为函数 A 的 prototype 对象[/b]
问题:
1) 如果函数 A 修改 prototype 对象,会直接影响到函数 B。
如果函数 B 的 prototype 属性又被函数 C 引用,则会出现修改冲突和混乱。
2) 函数 A 的与函数 B 共享一个 prototype ,共享一个 prototype.constructor
这显然不对。
[b]2、new 一个其它函数的实例,把它赋值给新函数的 prototype 属性[/b]
函数的 prototype 属性不就是一个对象吗(虽然具有特定的 constructor 属性)?
那我们给它一个好了。
问题:
1) 我们只是关心继承其它函数的 prototype 属性,而非this属性。
当使用 new 操作符时,无疑增加了不必要的原函数的 this 属性。
注意:
1) 新生成的其它函数的实例,没有 constructor 属性(虽然其 __proto__ 中有),
但这不是我们想要的。正好手动为其添加一个 constructor 属性,指向新函数自身。
[b]3、“方法 2”的扩展 [/b]
方法 2 在功能上已经实现了我们想要的。只是多了不必要的父类中this对象中的属性。
那好,只需去掉 this 对象(或只抽取其 prototype 对象)即可。
借助于空函数 F(){} 和修改 F 的 prototype,
我们构造了一个只含有 Animal 的 prototype 属性的“简洁的 Animal”:F 。
将上述方法封装为一个函数:
[b]结语:[/b]
原型继承又叫方法函数继承。
因为我们通常把有用的方法写到函数的 prototype 属性中。
属性继承又叫this属性继承。
它主要是通过传递this的引用给其它函数,而使this具有额外的属性。
—————————————
javascript 函数基础系列文章
[url=http://lixh1986.iteye.com/blog/1955314]1、JavaScript之变量的作用域[/url]
[url=http://lixh1986.iteye.com/blog/2028899]2、javascript之变量类型与变量声明及函数变量的运行机制[/url]
[url=http://lixh1986.iteye.com/blog/1947017]3、javaScript之function定义[/url]
[url=http://lixh1986.iteye.com/blog/1896682]4、javascript之function的prototype对象[/url]
[url=http://lixh1986.iteye.com/blog/1891833]5、javascript之function的(closure)闭包特性[/url]
[url=http://lixh1986.iteye.com/blog/1960343]6、javascript之function的this[/url]
[url=http://lixh1986.iteye.com/blog/1943409]7、javascript之function的apply(), call()[/url]
___________
javascript 面向对象编程系列文章:
[url=http://lixh1986.iteye.com/blog/1958956]1、javaScript之面向对象编程[/url]
[url=http://lixh1986.iteye.com/blog/2332467]2、javascript之面向对象编程之属性继承[/url]
[url=http://lixh1986.iteye.com/blog/2348442]3、javascript之面向对象编程之原型继承[/url]
-
-
转载请注明,
原文出处:http://lixh1986.iteye.com/blog/2348442
-
[size=medium][b]背景知识:[/b][/size][url=http://lixh1986.iteye.com/blog/1896682][size=medium][b]什么是函数的 prototype 属性?[/b][/size][/url]
函数在定义(创建)时,会自动被添加一个 prototype 属性。
1、prototype 属性是一个空对象 {},然后被添加了一个 constructor 属性,指向函数自身。
2、prototype 属性被函数(使用 new 操作符生成)的实例共享。
3、在访问函数实例的某个属性时,如果该属性不存在,则向其 __proto__ 属性中寻找,如果仍然不存在则向其 __proto__ 属性的 __proto__属性中寻找,直至根。
//
function F(){}
//test
console.log(F == F.prototype.constructor); // true
//
//
function F(){}
F.prototype.title = "hello";
//test
var f1 = new F();
var f2 = new F();
console.log(f1.title); // hello
console.log(f2.title); // hello
//
[color=gray]再补充一句:constructor 的意义?
由于
1) constructor 属性,指向函数自身。
2) prototype 属性被函数的实例共享。
3) constructor 属性是 prototype 的一部分。
所以函数的各个实例便可以通过 constructor 属性确定,它们来自于同一个构造函数。[/color]
[size=medium][b]一、继承其它函数的 prototype 属性[/b][/size]
函数 A(即将要被创建)的 prototype 属性是空的,未被使用的。
函数 B 的 prototype 属性将被函数 A 继承。
有以下方案:
[b]1、直接引用函数 B 的 prototype 对象作为函数 A 的 prototype 对象[/b]
function Animal(){}
function Dog(){};
Dog.prototype = Animal.prototype;
//test
var dog = new Dog();
console.log(dog.constructor == Dog ); // false
问题:
1) 如果函数 A 修改 prototype 对象,会直接影响到函数 B。
如果函数 B 的 prototype 属性又被函数 C 引用,则会出现修改冲突和混乱。
2) 函数 A 的与函数 B 共享一个 prototype ,共享一个 prototype.constructor
这显然不对。
[b]2、new 一个其它函数的实例,把它赋值给新函数的 prototype 属性[/b]
函数的 prototype 属性不就是一个对象吗(虽然具有特定的 constructor 属性)?
那我们给它一个好了。
//
function Animal(){}
Animal.prototype.type = "Animal";
function Dog(){};
//1. var dog_constructor = Dog.prototype.constructor;
//2. Dog.prototype = new Animal();
//3. Dog.prototype.constructor = dog_constructor;
//4. dog_constructor == Dog // true
var animal = new Animal();
Dog.prototype = animal;
Dog.prototype.constructor = Dog;
//test
var dog = new Dog();
console.log(dog.constructor == Dog ); // true
console.log(dog.type == "Animal" ); // true
//
问题:
1) 我们只是关心继承其它函数的 prototype 属性,而非this属性。
当使用 new 操作符时,无疑增加了不必要的原函数的 this 属性。
注意:
1) 新生成的其它函数的实例,没有 constructor 属性(虽然其 __proto__ 中有),
但这不是我们想要的。正好手动为其添加一个 constructor 属性,指向新函数自身。
[b]3、“方法 2”的扩展 [/b]
方法 2 在功能上已经实现了我们想要的。只是多了不必要的父类中this对象中的属性。
那好,只需去掉 this 对象(或只抽取其 prototype 对象)即可。
//
function Animal(){}
function Dog(){};
Animal.prototype.type = "Animal";
function F(){};
F.prototype = Animal.prototype;
Dog.prototype = new F();
Dog.prototype.constructor = Dog;
//test
var dog = new Dog();
console.log(dog.constructor == Dog ); // true
console.log(dog.type == "Animal" ); // true
//
借助于空函数 F(){} 和修改 F 的 prototype,
我们构造了一个只含有 Animal 的 prototype 属性的“简洁的 Animal”:F 。
将上述方法封装为一个函数:
Function.prototype.extendPrototypeFrom = function(Parent){
var constructor = this.prototype.constructor;
function F (){};
F.prototype = Parent.prototype;
this.prototype = new F();
this.prototype.constructor = constructor;
}
//test
function Animal(){}
function Dog(){};
Animal.prototype.type = "Animal";
Dog.extendPrototypeFrom(Animal);
//test
var dog = new Dog();
console.log(dog.constructor == Dog ); // true
console.log(dog.type == "Animal" ); // true
[b]结语:[/b]
原型继承又叫方法函数继承。
因为我们通常把有用的方法写到函数的 prototype 属性中。
属性继承又叫this属性继承。
它主要是通过传递this的引用给其它函数,而使this具有额外的属性。
—————————————
javascript 函数基础系列文章
[url=http://lixh1986.iteye.com/blog/1955314]1、JavaScript之变量的作用域[/url]
[url=http://lixh1986.iteye.com/blog/2028899]2、javascript之变量类型与变量声明及函数变量的运行机制[/url]
[url=http://lixh1986.iteye.com/blog/1947017]3、javaScript之function定义[/url]
[url=http://lixh1986.iteye.com/blog/1896682]4、javascript之function的prototype对象[/url]
[url=http://lixh1986.iteye.com/blog/1891833]5、javascript之function的(closure)闭包特性[/url]
[url=http://lixh1986.iteye.com/blog/1960343]6、javascript之function的this[/url]
[url=http://lixh1986.iteye.com/blog/1943409]7、javascript之function的apply(), call()[/url]
___________
javascript 面向对象编程系列文章:
[url=http://lixh1986.iteye.com/blog/1958956]1、javaScript之面向对象编程[/url]
[url=http://lixh1986.iteye.com/blog/2332467]2、javascript之面向对象编程之属性继承[/url]
[url=http://lixh1986.iteye.com/blog/2348442]3、javascript之面向对象编程之原型继承[/url]
-
-
转载请注明,
原文出处:http://lixh1986.iteye.com/blog/2348442
-