摘要:本文章记录本人在学习中看书理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习。但是在开发的过程中,并不是所有的代码复用都会使用到继承。而且整个代码都无法按照预期来运行。为了修复绑定对象与方法之间的关系。
js 中复用代码本文章记录本人在学习 JavaScript 中看书理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习。
说道代码复用,一般都会涉及到对象继承。在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()分别借用方法:
// call notmyobj.doStuff.call(myobj, param1, p2, p3); // apply notmyobj.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
最后,如果文章有什么错误和疑问的地方,请指出。与sf各位共勉!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/85800.html
摘要:属性校验随着应用的增长,确保你的组件正确使用是有必要的。混入在当中,组件复用能够减少我们的代码量。官方举例说明的一种情况一个组件,每隔一段时间更新一次。提供了组件生命周期的方法告诉我们组件什么时候被创建和销毁。 当我们在设计接口的时候,将一些常见的设计元素(如按钮、表单、布局等)拆分成有着良好接口的可重用的组件。这样的话,下次你构建UI的时候只要写少量的代码。 属性校验 随着应用的...
摘要:最近一段时间在学习,由于觉得直接使用它需要加载很多的文件,因此想使用来实现异步加载,并动态注入控制器。手动启动,特别说明此处的不是那个框架,而是的一个手动启动框架的函数中完成了各模块的初始化,并且引入了。 最近一段时间在学习angularjs,由于觉得直接使用它需要加载很多的js文件,因此想使用requirejs来实现异步加载,并动态注入控制器。简单搜索了下发现好多教程写的都很复杂,所...
摘要:注本文首发于个人博客学习笔记。最近看了下变量,又名自定义属性,跟大家分享一下我的学习笔记。使用自定义属性来设置变量名,并使用特定的来访问。二学习笔记声明调用声明方式变量声明的方式非常简单,如下,声明了一个名叫的变量。 注:本文首发于个人博客 《CSS Variables学习笔记》。 最近看了下CSS Variables(CSS变量,又名CSS自定义属性),跟大家分享一下我的学习笔记。 ...
摘要:二还有一点也是思想不容易转过弯的一点,就是我在学习前端时,接触的思想都是需要我们将者分开,方便维护。但是在学习了接触了单文件组件之后,世界又变了,又让我们将同一个组件的放到一个文件中,这样又便于维护和复用,这一脸的懵那啥。 Vue.js 介绍 官方介绍: Vue.js是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图...
摘要:第二个是其值是或,确认是否深入监听。一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到第三个是其值是或,确认是否以当前的初始值执行的函数。混合定义来分发组件中的可复用功能结束,撒花文章已同步我的笔记,欢迎大家加,加后人生更加美好 vue.js记录 文章已同步我的github笔记https://github.com/ymblog/blog,欢迎大家加star~~,加star后...
阅读 3096·2023-04-26 00:49
阅读 3749·2021-09-29 09:45
阅读 1040·2019-08-29 18:47
阅读 2767·2019-08-29 18:37
阅读 2747·2019-08-29 16:37
阅读 3313·2019-08-29 13:24
阅读 1796·2019-08-27 10:56
阅读 2364·2019-08-26 11:42