面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装、继承、多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义JS中对象:无序属性的集合,其属性可以包含基本值、对象或者函数。可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。
面向对象编程实质就是创建对象。
构建对象的方法有多种:
工厂模式 || 构造函数模式 || 原型模式 || 组合模式(组合构造函数及原型模式)|| 动态原型模式
其中最常用组合模式,下面就使用的是组合模式
1.定义原型|基类
basicRender.js var BasicRender = { init: function(opt) { this.opt = opt; this.videoId = opt.videoId; this.type = opt.type; this.initApi(); this.fetch(); }, initApi: function() { this.api = 'http://v.baidu.com/'+ this.type + '_intro/?dtype=' + this.type + 'PlayUrl&service=json&e=1&id=' + this.videoId; }, fetch: function() { var self = this; var successCb = function(data) { self.updateData(data); self.beforeRender(data); self.render(); self.afterRender(); }; var failCb = function(e) { self.renderFail(e); }; $.ajax({ url: self.api, dataType: 'jsonp', success: successCb, error: failCb }); }, updateData: function(data) { }, beforeRender: function(data) { }, render: function(data) { }, afterRender: function(data) { }, renderFail: function(e) { } }; module.exports = BasicRender;
使用1:
var BasicRender = require('./BasicRender.js'); var renderHeader = function(opt) { this.init(opt); }; renderHeader.prototype = BasicRender; module.exports = function(opt){ renderHeader(opt); };
报错如下:
Uncaught TypeError: this.init is not a function
分析:
直接执行renderHeader方法,this指向window,没有init方法。如果想要用此方法需要this指向实例,下面是第二种方法
使用2:
var BasicRender = require('./BasicRender.js'); var renderHeader = function(opt) { this.init(opt); this.render = fucntion(data) { console.log(data); } }; renderHeader.prototype = BasicRender; module.exports = function(opt){ new renderHeader(opt); };
输出数据data,正确
分析:renderHeader方法中this指向实例。
正确实现继承。
使用3:
防止prototype污染:
var BasicRender = require('./BasicRender.js'); var renderHeader = function(opt) { this.init(opt); this.render = fucntion(data) { console.log(data); } }; $.extend(renderHeader.prototype, BasicRender); module.exports = function(opt){ new renderHeader(opt); };
用以下伪代码表示继承实现:
var BasicRender = { init: function(opt) { this.opt = opt; this.initApi(); this.fetch(); }, fetch: function() { }, initApi: function() { } }; var Func = function(config) { this.init(config); this.fetch = function() { }; }; $.extend(Func.prototype, BasicRender); var funcObj = new Func(config);
参考文章:
JS面向对象的程序设计
Pingback引用通告: 熊二的技术博客