prototype基础
简介
在JavaScript中,prototype对象是实现面向对象的一个重要机制。
每个函数就是一个对象(Function),函数对象都有一个子对象 prototype对象,类是以函数的形式来定义的。
prototype表示该函数的原型,也表示一个类的成员的集合。
在通过new创建一个类的实例对象的时候,prototype对象的成员都成为实例化对象的成员。
1、该对象被类所引用,只有函数对象才可引用;
2、在new实例化后,其成员被实例化,实例对象方可调用。
同时,函数是一个对象,函数对象若直接声明成员,不用被实例化即可调用。
-- 百度百科
prototype是对象的一个类属性, 在其下面可以挂载一些var和function, 当然也可以使用其他对象对其进行赋值;
prototype最大的作用是在进行内部访问时, 支持访问元素的检索沿着prototype向下遍历, 从而实现类际的有基础的拓展;
prototype支持js实现对象的继承特点, 但和java面向对象语言等又有着很大的不同, 最大区别的来源在于对象是即时更新的,
即基类属性被修改之后, 父类功能在js中不会受到影响, 所以js的继承更像是一种克隆, 在prototype赋值的时候对目标类的实例化
对象进行引用; 而之后对目标类的修改不会影响到之前的子类;
-- 个人理解
正文
包括3部分: 方法分类/对象基础/调用原型方法及this的作用域
方法分类:
js方法分为3种: 类方法/对象方法/原型方法.
对象方法可以理解为java的成员方法, 必须通过类实例化对象进行调用;
类方法对静态方法, 可通过类名和对象进行调用;
原型方法是对象静态属性prototype(多级)所拥有的方法.
1 function ClassA(){ 2 this.vari = 'member attributr'; 3 this.func = function(){ 4 alert('member function'); 5 } 6 } 7 ClassA.statA = 'static attribute'; 8 ClassA.statF = function(){ 9 alert('static function'); 10 } 11 function CalssB(){ 12 13 } 14 ClassB.prototype = new ClassA(); // ClassA为ClassB的原型, ClassA属性为ClassB的原型属性, ClassA的方法为ClassB的原型方法
注: 原型属性和原型方法是非静态的, 即不是原型的类属性和类方法, 这个稍后会介绍到.
对象基础:
这里首先讲到的是function与对象的关系:
我的理解是function可以理解为一种特殊的变量, 只不过var变量可以直接访问, 而function在var的基础上可以使用括号"()"对其以可执行代码的方式
执行; 而通过new function_name可以得到一个对象, 在其内部会自动内置一个prototype属性来支持实现原型拓展;
1 function Father(){ 2 this.say = function(){ 3 alert('this is father.'); 4 } 5 } 6 // ------- 或 ------- 7 // var Father = function(){ 8 // this.say = function(){ 9 // alert('this is father.'); 10 // } 11 // } 12 var father = new Father(); 13 father.say();
# 方法属性的继承
成员方法和属性被继承, 且在子类出现同名时被覆盖;
静态方法无法继承;
1 Father.name = 'father' 2 Father.run = function(){ 3 alert('father run.'); 4 } 5 function Child(){ 6 7 } 8 Child.prototype = new Father(); 9 var child = new Child(); 10 child.say(); 11 alert(child.name); // undefined 12 child.run(); // 出错:对象不支持此属性和方法
# function内部的组成及执行时机
组成大致可分为3种: 变量的定义, function的定义, 可执行代码;
其中var和function在new时完成初始化, 可被访问;
可执行代码在new时被执行;
1 function Func(){ 2 alert('alert function'); 3 this.name = 'func'; 4 this.func = function(){ 5 alert('func-alert'); 6 } 7 } 8 var f = new Func(); // 提示: alert function 9 alert(f.name); // 提示: func 10 f.func(); // 提示: func-alert
# 内部方法
即function内部的function, 且在内部可执行代码执行之前完成加载;
1 function F1(){ 2 alert('f1'); 3 F2(); // 在F2定义前调用执行, 显示: f2 4 function F2(){ 5 alert('f2'); 6 } 7 } 8 $(function(){ 9 F1(); 10 });
原型方法的调用和this关键字的作用域
使用fatherInstance.fatherFunctionName.call(childInstance), 完成调用子类的原生方法
1 var Father = function(){ 2 this.say = function(){ 3 alert('this is father.'); 4 } 5 } 6 function Child(){ 7 this.say = function(){ 8 alert('this is child.'); 9 } 10 } 11 Child.prototype = new Father(); 12 var child = new Child(); 13 child.say(); // 提示: this is child. 14 var father = new Father(); 15 father.say.call(child); // 提示: this is father.
this关键字的作用域指向其所调用对象:
1 var Father = function(){ 2 this.name = 'father' 3 this.say = function(){ 4 alert(this.name); 5 } 6 } 7 function Child(){ 8 this.name = 'child'; 9 this.say = function(){ 10 alert(this.name); 11 } 12 } 13 Child.prototype = new Father(); 14 var child = new Child(); 15 child.say(); // 提示: this is child. 16 var father = new Father(); 17 father.say.call(child); // 提示: this is child.
我们不创造代码, 我们只是大自然的搬运工.
浙公网安备 33010602011771号