JS代码复用
js 中复用代码
说道代码复用,一般都会涉及到对象继承。在js中有许多可以选择的继承方法。这些方法对于学习和理解多种不同的模式有很大的好处,因为它们有助于提供对语言的掌握程度。
但是在开发的过程中,并不是所有的代码复用都会使用到继承。其中一部原因在于,事实上使用的js库可能以这样的或那样的方式解决了该问题。而另一方面的原因就在于很少需要在js中建立长而且复杂的继承链。在静态强类型语言中,继承可以能是唯一复用代码的方法。在js中,经常有更加简洁而且优美的方法。包括:借用方法、绑定、复制属性以及从多个对象中混入属性等许多方法。
混入
混入是针对通过属性复制实现继承的思想做进一步的扩展,mix-in模式并不是复制一个完整的对象,而是从多个对象中复制出任意的成员并将这些成员组合成新的对象。
实现mix-in:
function mix() { var arg, prop, child = {}; for (arg = 0; arg arguments.length; arg += 1) { for (prop in arguments[arg]) { if (arguments[arg].hasOwnProperty(prop)) { child[prop] = arguemnts[arg][prop]; } } } return child; }
mix-in实现非常简单,只需要遍历每个参数,并且复制出传递给该函数的每个对象中的每个属性。
借用方法
有的时候,我们只需要对象中的一两个方法,但是又不想和对象形成父-子继承关系。只是想是用所需要的方法,而不希望继承所有那些永远用不到的属性和方法。在这种情况下,可以通过使用借用方法模式来实现。
而这个方法是受益于call()和apply()的。js中函数也是对象,并且它们自身也存在一些属性和方法,比如call和apply()。
使用call()和apply()分别借用方法:
// callnotmyobj.doStuff.call(myobj, param1, p2, p3); // applynotmyobj.doStuff.apply(myobj, [param1, p2, p3]);
在知道notmyobj对象上有doStuff方法的情况下,又想不继承notmyobj来使用doStuff方法。这个使用call()和apply()就派上用场了。
还有一个场景是经常使用到借用方法的。那就是借用数组方法。因为数据具有许多很强大的方法,而且有时候需要操作arguments的时候会用上。但是arguments是一个伪数组,不具有原生数组强大的方法。这个使用借用方法就派上用场了:
function f() { var args = [].slice.call(arguemnts, 1, 3); return args; }
借用和绑定
考虑到借用方法不是通过调用call和apply()就是通过简单的复制,在借用方法的内部,this所指向的对象是基于调用表达式而确定的,但是有的时候“锁定”this的值,或者将其绑定到特定的对象并且预先确定该对象。
举一栗子:
var one = { name: object, say: function (greet) { return greet + ", " + this.name; } };
// 测试 one.say(hi); // hi, object 接着另一对象two中没有say()方法,借用one的say()方法:
var two = { name: another object }
// 测试 one.say.call(two, hi); // hi, another object 在上面的例子中,借用的say()方法的this是指向two的。但是在什么样的场景中,应该将函数指针赋值给一个全局变量,或者将该函数做为回调函数来传递?在客户端编程中有许多事件和回调,因此确实发生了许多这样混淆的事件。
举一个栗子:
// 给变量赋值 // this 将指向全局变量 var say = one.say;say(hello) // hello, undefined // 作为回调传递 var yetanother = { name: yet another object, method: function (callback) { return callback(hola); } };
// 测试 yetanother.method(one.say) // holla, undefined 在上面的两种情况下,say()方法的this值都是指向全局对象。而且整个代码都无法按照预期来运行。为了修复(绑定)对象与方法之间的关系。可以使用一个简单的函数来实现:
function bind(o, m) { return function () { return m.apply(o, [].slice.call(arguments)) } }
上面的bind()方法接受两个参数。一个是对象o,另一个是方法m,并将两者绑定起来。然后返回一个函数。
使用bind()来解决问题:
var twosay = bind(two, one.say); twosay(yo); // yo another object
奢侈的拥有绑定所需要辅助的代价就是额外的闭包的开销。 ES5 bind()
在ECMAScript5中给Function.protoype添加了一个bind()方法,使得bind()与call()、apply()一样简单易用。
但是在不支持ECMAScript5的运行环境下,我们可以自己实现一个bind()方法(来自 MDN):
if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 internal IsCallable function throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () {}, fBound = function () { return fToBind.apply(this instanceof fNOP oThis ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }
然后使用自带的bind()方法来重写一下上面的栗子:
var twosay = bind(two, one.say); twosay(Bonjour); // yo another object
js 面向对象详解 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就行了。
JS基础-面向对象 JavaScript、Java、c#.... 面向对象:JavaScript有些区别! 类:模板 原型对象 对象:具体的实例 在JavaScript这个需要大家换一下思维方式! 原型:
js中的模块化一 js中的模块化一:我们知道最常见的模块化方案有CommonJS、AMD、CMD、ES6,AMD规范一般用于浏览器,异步的,因为模块加载是异步的,js解释是同步的,所以有时候导致依赖还没加载完毕,同步的代码运行结束;CommonJS规范一般用于服务端,同步的,因为在服务器端所有文件都存储在本地的硬盘上,传输速率快而且稳定。
js中的模块化二 web前端教程接下来降为大家继续分享js中的模块化知识4.循环依赖就是a依赖b,b依赖a,对于不同的规范也有不同的结果。4.1CommonJS对于node,每一个模块的exports={done:false}表示一个模块有没有加载完毕,经过一系列的加载最后全部都会变为true。
相关文章
- 图片旋转,鼠标滚轮缩放,镜像,切换图片js代码
- Node.js压缩与解压数据
- 判断浏览器内核JS代码
- js substr和substring
- vue.config.js常用配置详解
- js和jquery获取父级元素、子级元素、兄弟元素的方法{转}
- [DOT] Polkadot-js 的官方资源
- 为什么Note.js 里面没有sap.ui.core.Control.extend()这样的代码,但是runtime有自动生成有
- 经过 Webpack 处理过的 SAP Spartacus main.js
- 如何从ngrx-store-devtools.js里找到actions的触发源头
- Atitit stomp.js conn连接activemq 目录 1.1. activemq 启动,已经默认开启了stomp ws的接口。。地址是1 1.2. Js 客户端代码1 1.3
- Atitit 研发体系 codelib 代码库的建设 目录 1. 概念与组成2 1.1. Java代码2 1.2. Js代码2 1.3. H5 代码 js+css+htm+txt2 1.4.
- Atitit.js javascript的rpc框架选型
- paip.关于动画特效原理 html js 框架总结
- 华为OD机试 - 查找重复代码(Java & JS & Python)
- 华为OD机试 - 按索引范围翻转文章片段(Java & JS & Python)
- 原生js实现随机验证码HTMl-JS
- js工具代码封装(超长)1/3
- Atom编辑器折腾记_(15)JS代码片段补全(插件:javascript-snippets)
- 如何在VUE单页面引入CSS、JS(CDN链接)
- JS:crypto-js实现AES加密解密
- springboot拦截器拦了静态资源css,js,png,jpeg,svg等等静态资源
- 原生js实现随机验证码HTMl-JS
- js工具代码封装(超长)1/3
- Web前端 | HTML嵌入JS代码的三种方式