今天来实现一个简单的js框架,相似jq的功能,实现了增减class,增减属性,链式调用,合并对象等功能,html
更加深刻理解下js原型prototype
的应用,是以前承诺的原型模式应用的文章,欢迎评论交流vue
(function(window, document) { 'use strict'; // jq函数 var myJquery = function(selector){ return myJquery.fn.init(selector); } // 原型方法 myJquery.fn = myJquery.prototype = { // 修复原型链 constructor: myJquery, // 初始化方法 init: function(selector) { if(!selector) return; var el = document.querySelectorAll(selector); el = Array.from(el); // 设置原型 Object.setPrototypeOf(el,this); return el; } } // 将业务代码注册到全局命名空间 window.myJquery = window.$ = myJquery; })(window, document);
根据代码,能够看到首先,一个匿名自执行函数,而后在window上注册,而后就是原型上添加init方法,这是个常规操做了;es6
这里我没按照jq来,为了便于理解,我分红了三个方法设计模式
myJquery.fn = myJquery.prototype = { // 得到属性 getAttr: function(attr) { var i = 0, length = this.length; if(length === 0) return; if( length === 1){ return this[0].getAttribute(attr); } var arr = []; // 遍历 for (; i < length; i++) { arr.push(this[i].getAttribute(attr)); } return arr; }, // 设置属性 setAttr: function(attr,value) { var i = 0, length = this.length; if( length === 0) return; // 单一属性时候 if(typeof attr === 'string' && value !== undefined){ for (; i < length; i++) { this[i].setAttribute(attr,value); } } // 是对象时候 if(typeof attr === 'object'){ for (var key in attr) { if (attr.hasOwnProperty(key)) { for (var j = 0; j < length; j++) { this[j].setAttribute(key,attr[key]); } } } } return this; }, // 删除属性 removeAttr: function(attr) { var i = 0, length = this.length; if(length === 0) return; for (; i < length; i++) { this[i].removeAttribute(attr); } return this; } }
主要仍是要判断多种状况,扩展自定义框架的功能,让框架功能更增强大,我这考虑🤔了几种状况,不一样的参数类型,固然可能没有jq那么完善了,不过看看也便于理解框架了。api
每一个框架都会有的,我这作了一个合并对象的功能,扩展框架的没加,不过思路也是同样的框架
// 合并对象 myJquery.extend = myJquery.fn.extend = function() { var i = 0, deep = arguments[0] || {}, _obj = {}, length = arguments.length; // 浅拷贝 if(typeof deep === 'object'){ [...arguments].forEach(val=>{ if(typeof val === 'object'){ Object.assign(_obj,val); } }); return _obj; } // 深拷贝 if(typeof deep === 'boolean'){ [...arguments].forEach(val=>{ if(typeof val === 'object'){ Object.assign(_obj,JSON.parse(JSON.stringify(val))); } }); return _obj; } }
下面是总体的代码,这个简单框架实现了添加删除属性,加减class,等等内容,后续,拓展代码也是这样加,这是对js原型模式基本应用函数
// 原生js实现框架 (function(window, document) { 'use strict'; // jq函数 var myJquery = function(selector){ return myJquery.fn.init(selector); } // 原型方法 myJquery.fn = myJquery.prototype = { // 修复原型链 constructor: myJquery, // 初始化方法 init: function(selector) { if(!selector) return; var el = document.querySelectorAll(selector); el = Array.from(el); // 设置原型 Object.setPrototypeOf(el,this); return el; }, // 得到属性 getAttr: function(attr) { var i = 0, length = this.length; if(length === 0) return; if( length === 1){ return this[0].getAttribute(attr); } var arr = []; // 遍历 for (; i < length; i++) { arr.push(this[i].getAttribute(attr)); } return arr; }, // 设置属性 setAttr: function(attr,value) { var i = 0, length = this.length; if( length === 0) return; // 单一属性时候 if(typeof attr === 'string' && value !== undefined){ for (; i < length; i++) { this[i].setAttribute(attr,value); } } // 是对象时候 if(typeof attr === 'object'){ for (var key in attr) { if (attr.hasOwnProperty(key)) { for (var j = 0; j < length; j++) { this[j].setAttribute(key,attr[key]); } } } } return this; }, // 删除属性 removeAttr: function(attr) { var i = 0, length = this.length; if(length === 0) return; for (; i < length; i++) { this[i].removeAttribute(attr); } return this; }, // 添加内容 html: function(val) { var i = 0, length = this.length; if(length === 0 || val === undefined) return; for(;i<length;i++){ this[i].innerHTML = val; } return this; }, // 添加class addClass: function(clsName) { var i = 0, length = this.length; if(length === 0 || clsName === undefined) return; for(; i < length; i++){ var cla = this[i].className; cla += " " + clsName; this[i].className = cla.trim(); } return this; }, // 删除class removeClass: function(clsName) { var i = 0, length = this.length; if(length === 0 || clsName === undefined) return; var clsName = clsName.split(" "); for(; i<length; i++){ var cla = this[i].className; cla = cla.split(" "); // 为了简洁,用了点es6代码 clsName.forEach(val=>{ cla = cla.filter(value=>value !== val); }); cla = cla.join(' ').trim(); this[i].className = cla; } return this; }, } // 合并对象 myJquery.extend = myJquery.fn.extend = function() { var i = 0, deep = arguments[0] || {}, _obj = {}, length = arguments.length; // 浅拷贝 if(typeof deep === 'object'){ [...arguments].forEach(val=>{ if(typeof val === 'object'){ Object.assign(_obj,val); } }); return _obj; } // 深拷贝 if(typeof deep === 'boolean'){ [...arguments].forEach(val=>{ if(typeof val === 'object'){ Object.assign(_obj,JSON.parse(JSON.stringify(val))); } }); return _obj; } } // 将业务代码注册到全局命名空间 window.myJquery = window.$ = myJquery; })(window, document);
js框架,都很好的运用了prototype
原型,这是js开发中必需要掌握的内容,这篇文章是原型模式的应用,但愿对各位看官有所启发,this
接下来,我看看出几篇vue的文章,再试着作个vue的简单实现,vue的话主要运用了设计模式的观察者模式,主要用了Object.defineProperty
这个ES6的api,prototype
固然这篇文章就很少讲了,但愿你们看了有收获,谢谢你们观看😄!设计