美文网首页
关于extend的一些思考

关于extend的一些思考

作者: d6410a361d08 | 来源:发表于2017-04-23 16:57 被阅读0次

JS 拷贝是一个在我们开发中经常遇到的一个问题,我们通过使用extend这个函数来实现一些JS的复用。

比如下面的代码:

var _default = { address: "上海市静安区", sex: "男" };
var user = $.extend({}, _default,{name:"小亮", age:12});
console.log(user) //=> {name:"小亮", address: "上海市静安区",age:12}

这是一个开发中经常遇到的一个场景,我们通过复用一些默认的配置,减少了代码开发量。这里我是用的$.extend是jQuery提供的一个静态拷贝函数。它在这里的作用就是把_default 和 {name:"小亮",age:12}的属性合并到 {} 中,并且返回。

自己如何实现

作为一个程序员,我们不仅仅需要知其然,还是知其所以然,所以我们不仅是需要知道怎么使用,也需要明白其中的实现和原理,以及一些我们需要注意的事项。

第一步: 入口参数处理

extend = function (x, y, z, ......) { ...... }

extend这个函数的功能是把除第一个参数外,其它参数的属性合并到第一个参数,那我们是不知道总共有多少个参数,所以我们需要使用到 arguments 这个对象去获取参数,当然了,如果是在ES6的情况下,我们就不需要使用arguments这个参数对象了。

extend = function (x, y, z, ......) { console.log(arguments) //=> [x,y,z ......] console.log(arguments[0]) //=> x console.log(arguments[1]) //=> y ...... }

这里arguments 是一个类数组对象,可以通过arguments的下标获取相关的参数值,但是没有实现数组相关的方法。所以,我们有时候需要把arguments这个参数对象转化为数组。

var argus = Array.prototype.slice.call(arguments);

这样我们就能够获取extend函数的不定参数

第二步: 数据拷贝

在开始进行数据拷贝之前,我们应该需要确认两个问题。

  1. 我们获取到参数以后,第一个参数,应该是作为我们的base对象,后面的对象把他们的属性放到这个base对象上,而且是依次执行的。 这样的话,后面属性值会把前面的属性值给进行覆盖。

  2. 就是需要对参数类型进行判断, 按照日常的开发需求来说,我们这里是只需要纯 Object 对象,那么像Number,Boolean,String,Function, Array...... 这种如果出现在参数里面。那么从功能角度来说,这些数据是无用数据,所以这些数据会被过滤掉。

Object.prototype.toString.call(obj) === "[object Object]" //=> true

那么我们开始进入正题,实现extend的拷贝

var isObj = function (obj) { return Object.prototype.toString.call(obj) === "[object Object]"; };
var extend = function(base) { // argus 表示除 base 后面的列表集合 var argus = Array.prototype.slice.call(arguments,1),obj,key; base = isObj(base) ? base : {}; for (var index = 0, length = argus.length; index < length; index++) { obj = argus[index]; if (isObj(obj)) { // 防止非纯Object对象 for (key in obj) { if (obj.hasOwnProperty(key)) { base[key] = obj[key]; } } } } return base; }

测试用例

extend({},{a:1},{b:1}); //=> Object {a: 1, b: 1}
extend({a:1},{b:1}); //=> Object {a:1, b:1}
extend({},[1,2,3]); //=> Object {}
extend({},{aa : function() { alert("aa")}}); //=>Object{aa:()}
extend(null,{aa : 111 }); //=>Object{aa :111}

到此,我们已经完成了 extend 这个函数基本骨架。

相关文章

网友评论

      本文标题:关于extend的一些思考

      本文链接:https://www.haomeiwen.com/subject/azxqzttx.html