JavaScript面向对象二
2012-05-28 17:52
411 查看
一、理解篇: 1、每创建的一个函数都有一个prototype属性,该属性是一个对象,prototype默认有一个constructor属性,默认指向prototype对象所在函数的指针; 2、prototype对象中定义的属性和方法是实例化prototype所在函数对象所共享的,当prototype为字面量对象时,其constructor属性将指向Object构造函数; 3、在实例对象中默认有一个内部属性__proto__,该属性指向原型对象,即(构造函数中的prototype属性,实例对象的原型对象) 4、在一个函数被作为构造函数时,我们把在构造函数中定义的属性,方法称为实例属性和方法,把在prototype对象中定义的属性和方法,称为原型属性和方法; 二、属性篇: isPrototypeOf: 检查某对象是否是另一对象的原型 hasOwnProperty: 检测一个属性是否存在于实例中 in: 只要属性能够被实例所访问,就返回true,无论属性是否存在原型还是实例中 for-in: 通过for循环,返回所有可以枚举的属性(在ie6中存在一个bug,即被打上[[DontEnum]]不可枚举的标签属性不会被返回,而其他浏览器则屏蔽了不可枚举的属性,即也会被返回) 三、模式篇: 1、工厂模式
function obj(arg1,arg2){ var o = new Object(); o.arg1 = arg1; o.arg2 = arg2; o.method = function(){ console.log(arg1+arg2); } return o; } var obj1 = obj(10,20); obj1.method(); //30
缺点:对象不识别类型 2、构造函数模式
function Obj(arg1,arg2){ this.arg1 = arg1; this.arg2 = arg2; this.method = function(){ console.log(arg1+arg2); } } var obj1 = new Obj(10,20); obj1.method(); //30
缺点:方法不能重用 3、原型模式
function Obj(){} Obj.prototype = { constructor: Obj, arg3: ["a","b","c"], method: function(){ console.log(this.arg3.toString()); } } var obj1 = new Obj(); obj1.method(); //a,b,c var obj2 = new Obj(); obj2.arg3.push("d"); obj1.method(); //a,b,c,d
缺点:原型对象存在引用类型属性时,此属性在实例对象上的修改会影响到另一个实例的共享属性 4、组合使用构造函数模式和原型模式
function Obj(arg1,arg2){ this.arg1 = arg1; this.arg2 = arg2; this.arg3 = ["a","b","c"]; } Obj.prototype = { constructor: Obj, method: function(){ console.log(this.arg1+this.arg2); } } var obj1 = new Obj(10,20); obj1.method(); //30 var obj2 = new Obj(); obj2.arg3.push("d"); console.log(obj1.arg3.toString()); //a,b,c
优点:在不涉及继承时,此模式为最佳模式 5、动态原型模式
function Obj(arg1,arg2){ this.arg1 = arg1; this.arg2 = arg2; if(typeof this.method != "function"){ Obj.prototype.method = function(){ console.log(this.arg1+this.arg2); } } } var obj1 = new Obj(10,20); obj1.method(); //30
缺点:在实例化对象后不能再重写原型,否则会切断现有原型与实例的关系 6、寄生构造函数模式
function Obj(arg1,arg2){ var o = new Object(); o.arg1 = arg1; o.arg2 = arg2; o.method = function(){ console.log(this.arg1+this.arg2); } return o; } var obj1 = new Obj(10,20); obj1.method(); //30
缺点:与工厂模式类似,不建议使用该模式 7、稳妥构造函数模式
function Obj(arg1){ var o = new Object(); o.method = function(){ console.log(arg1); } return o; } var obj1 = Obj(10); obj1.method(); //10
说明:此模式只能通过method方法才能访问arg1变量,即:目的是为了在安全环境中执行 8、原型链
function Super(arg1,arg2){ this.arg1 = arg1; this.arg2 = arg2; this.arg3 = ["a","b","c"]; } Super.prototype = { constructor: Super, superMethod: function(){ console.log(this.arg3.toString()); } } function Sub(){ } Sub.prototype = new Super(); Sub.prototype.constructor = Sub; var obj1 = new Sub(); obj1.superMethod(); //a,b,c var obj2 = new Sub(); obj2.arg3.push("d"); obj1.superMethod(); //a,b,c,d
缺点:只要是原型对象中存在引用类型属性,那么就会出现单独使用原型模式遇到的问题 9、借用构造函数
function Super(){ this.arg3 = ["a","b","c"]; } function Sub(){ Super.call(this); } var superObj = new Super(); superObj.arg3.push("d"); var obj1 = new Sub(); console.log(obj1.arg3.toString()); //a,b,c
说明:在一个构造函数中调用另一个构造函数,即:在一个作用域中执行另一个作用域中要执行的代码 10、组合继承
function Super(arg1,arg2){ this.arg1 = arg1; this.arg2 = arg2; this.arg3 = ["a","b","c"]; } Super.prototype = { constructor: Super, superMethod: function(){ console.log(this.arg3.toString()); } } function Sub(){ Super.call(this,10,20); //在实例化对象时,此句会调用超类构造函数 } Sub.prototype = new Super(); //第一次调用超类构造函数 var obj1 = new Sub(); obj1.superMethod(); //a,b,c var obj2 = new Sub(); //第二次调用超类构造函数 obj2.arg3.push("d"); obj1.superMethod(); //a,b,c
说明:此模式是继承原型链与借用构造函数模式中的优点,但也有缺点,即:在每次实例化子类对象时,都会调用两次超类构造函数 11、原型式继承
function object(o){ function F(){} F.prototype = o; return new F(); } var o = { arg1: 10, method: function(){ console.log(this.arg1); } } var obj1 = object(o); obj1.method();
说明:注意object函数返回的是以对象o为原型对象的实例对象 12、寄生式继承
function object(o){ function F(){} F.prototype = o; return new F(); } var o = { arg1: 10, method: function(){ console.log(this.arg1); } } function createAnother(original){ var clone = object(original); clone.sayHi = function(){ alert("hi"); } return clone; } var obj1 = createAnother(o); obj1.sayHi(); //hi
说明:与原型式继承模式类似,只不过在返回的实例对象上增加了行为 13、寄生组合式继承
function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType,superType){ var prototype = object(superType.prototype); //获得以superType.prototype为原型对象的临时对象,因此临时对象拥有这个原型对象的所有属性和方法 prototype.constructor = subType; //为prototype这个临时对象初始化constructor属性值 subType.prototype = prototype; //将子类的prototype赋值为这个临时对象,因此子类的实例化对象共享这个临时对象(即:也共享超类构造函数中的prototype属性)中的所有属性和方法 } function Super(arg1,arg2){ this.arg1 = arg1; this.arg2 = arg2; } Super.prototype = { constructor: Super, superMethod: function(){ console.log(this.arg1+this.arg2); } } function Sub(arg1,arg2){ Super.call(this,arg1,arg2); } inheritPrototype(Sub,Super); var obj1 = new Sub(10,20); obj1.superMethod(); //30 console.log(obj1.constructor); //Sub(arg1,arg2){ xxx } var superObj = new Super(); console.log(superObj.constructor); //Super(arg1,arg2){ xxx }
说明:此模式是继承组合式继承和寄生式继承的优点,该模式为最佳模式 14、jQuery核心框架
var $ = Fn = jQuery = function(){ return new Fn.prototype.init(); } Fn.prototype = jQuery.prototype = { init: function(){ return this; }, method1: function(){ console.log("method1"); }, method2: function(){ console.log("method2"); } } Fn.prototype.init.prototype = Fn.prototype;
说明: 以上代码不是上面任何模式中的一种,也没有涉及到选择器,只是模拟jQuery核心框架代码,该代码中涉及到函数返回值,原型对象以及继承。 首先,jQuery指定的函数中返回一个实例化对象,这个返回的实例化对象是以jQuery函数中的原型属性中的init方法作为构造函数,init方法返回this, 此this并不会污染上一级作用域,因为它指向的是实例化init构造函数的对象,即jQuery函数中返回的对象; 将init方法的原型属性赋值为jQuery函数的原型属性,那么jQuery函数的返回对象就会共享jQuery函数的原型属性中的属性和方法。 使用方法:
var obj = $(); obj.method1(); //method1
[注:此文章是总结JavaScript高级程序设计第二版中第六章面向对象]
相关文章推荐
- 详解JavaScript基于面向对象之继承实例
- 一篇笔记带你快速掌握面向对象的Javascript(纯手打)
- JavaScript面向对象
- prototype.js 让你更深入的了解javascript的面向对象特性
- 全面理解面向对象的 JavaScript
- Javascript面向对象三大特性(封装性、继承性、多态性)详解及创建对象的各种方法
- JavaScript 面向对象
- JavaScript面向对象之类的继承
- javascript面向对象学习笔记(一)——继承
- 面向对象的JavaScript
- JavaScript面向对象之Prototypes和继承
- 面向对象的Javascript
- 回顾JavaScript基础知识小结2-面向对象(介绍)
- JavaScript面向对象
- (一)面向对象的javascript
- 面向对象的 JavaScript 编程及其 Scope 处理
- JavaScript面向对象中的属性,对象创建,继承
- 深入javascript面向对象,js的原型链、继承
- Javascript面向对象及组件开发(二)面向对象的写法
- 如何理解并学习javascript中的面向对象(OOP)