前言
今天来实现一个简单的js框架,类似jq的功能,实现了增减class,增减属性,链式调用,合并对象等功能,
更加深入理解下js原型prototype
的应用,是之前承诺的原型模式应用的文章,欢迎评论交流
初始化方法
(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方法,这是个常规操作了;
设置、获取、删除属性值
这里我没按照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那么完善了,不过看看也便于理解框架了。
扩展方法
每个框架都会有的,我这做了一个合并对象的功能,扩展框架的没加,不过思路也是一样的
// 合并对象
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开发中必须要掌握的内容,这篇文章是原型模式的应用,希望对各位看官有所启发,
接下来,我看看出几篇vue的文章,再试着做个vue的简单实现,vue的话主要运用了设计模式的观察者模式,主要用了Object.defineProperty
这个ES6的api,
当然这篇文章就不多讲了,希望大家看了有收获,谢谢大家观看?!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。