资讯专栏INFORMATION COLUMN

JavaScript 实现 extend

Nekron / 1482人阅读

摘要:最近在写移动端的项目,目前还没有引用任何库,所以很多的方法都要自己写。是没有这个原生方法的,今日得闲,就自己实现一个吧。文档中描述的原型是它的含义是将合并到中,并返回合并过的。

最近在写移动端的项目,目前还没有引用任何库,所以很多的方法都要自己写。

用惯了jQuery,当函数参数是对象的时候,定义默认参数的时候会写一个defaultOptions对象,然后通过jQuery.extend将实参扩展到defaultOptions对象上。JavaScript是没有extend这个原生方法的,今日得闲,就自己实现一个吧。

先想想这个函数需要做什么。jQuery extend文档中描述的jQuery.extend原型是
jQuery.extend( target [, object1 ] [, objectN ] )

它的含义是将object1、object2...合并到target中,并返回合并过的target。这里面有两个点需要注意一下。

合并是从后到前的;

target的值是被修改了的;

是深拷贝的(若是参数对象中有属性是对象,也是会递归合并的);

其实若不想原始数据被更改也很简单,只要第一个参数传空对象就好了。

那,直接上代吗吧:

void function(global){
    var extend,
        _extend,
        _isObject;

    _isObject = function(o){
        return Object.prototype.toString.call(o) === "[object Object]";
    }

    _extend = function self(destination, source){
        for (var property in source) {
            if (source.hasOwnProperty(property)) {

                // 若sourc[property]是对象,则递归
                if (_isObject(source[property])) {

                    // 若destination没有property,赋值空对象
                    if (!destination.hasOwnProperty(property)) {
                        destination[property] = {};
                    };

                    // 对destination[property]不是对象,赋值空对象
                    if (!_isObject(destination[property])) {
                        destination[property] = {};
                    };

                    // 递归
                    self(destination[property], source[property]);
                } else {
                    destination[property] = source[property];
                };
            }
        }
    }

    extend = function(){
        var arr = arguments,
            result = {},
            i;

        if (!arr.length) return {};

        for (i = 0; i < arr.length; i++) {
            if (_isObject(arr[i])) {
                _extend(result, arr[i])
            };
        }

        arr[0] = result;
        return result;
    }

    global.extend = extend;
}(window)

这样似乎可以了。但是貌似有一个小问题,我们这里是按照参数顺序从左到右依次执行的,但是其实若是最后一个参数有的属性,前面的参数上的该属性都不需要再扩展了。其实前面的所有参数都是将自己身上有的属性而最后一个参数没有的属性补到最后一个参数上。既如此,是不是从参数列表的右侧开始扩展更好一些。

修改以后的代码:

void function(global){
    var extend,
        _extend,
        _isObject;

    _isObject = function(o){
        return Object.prototype.toString.call(o) === "[object Object]";
    }

    _extend = function self(destination, source) {
        var property;
        for (property in destination) {
            if (destination.hasOwnProperty(property)) {

                // 若destination[property]和sourc[property]都是对象,则递归
                if (_isObject(destination[property]) && _isObject(source[property])) {
                    self(destination[property], source[property]);
                };

                // 若sourc[property]已存在,则跳过
                if (source.hasOwnProperty(property)) {
                    continue;
                } else {
                    source[property] = destination[property];
                }
            }
        }
    }

    extend = function(){
        var arr = arguments,
            result = {},
            i;

        if (!arr.length) return {};

        for (i = arr.length - 1; i >= 0; i--) {
            if (_isObject(arr[i])) {
                _extend(arr[i], result);
            };
        }

        arr[0] = result;
        return result;
    }

    global.extend = extend;
}(window)

写代码总是那么有意思!这里面可以看到,只要result身上有的属性,都不需要再赋值了,嘿嘿。

当然,目前水平有限,这段代码肯定也还有着优化空间,若看官有任何建议,还请不吝赐教。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78045.html

相关文章

  • JavaScript专题之从零实现jQuery的extend

    摘要:不过的实现中,多了很多细节上的判断,比如第一个参数是否是布尔值,是否是一个对象,不传参数时的默认值等。 JavaScritp 专题系列第七篇,讲解如何从零实现一个 jQuery 的 extend 函数 前言 jQuery 的 extend 是 jQuery 中应用非常多的一个函数,今天我们一边看 jQuery 的 extend 的特性,一边实现一个 extend! extend 基本用...

    wangtdgoodluck 评论0 收藏0
  • 元素选择器功能用实现Javascript

      本篇内容主要就是元素选择器功能用Javascript实现。  首先说下什么是元素选择器?  想必大家对于jquery很了解,知道它有对元素的查找功能,解释来说就是通过jquery的api获取页面元素的过程,该过程只需提供一个元素选择的条件字符串即可获取相应的满足条件的页面元素。元素选择器即是指通过条件字符串获取相应元素的一个工具函数。  元素选择器分为id选择器、class选择器、标签选择器以...

    3403771864 评论0 收藏0
  • JavaScript MVC 学习笔记(二)类的使用(上)

    摘要:任何函数都可以用做构造函数,构造函数必须使用运算符作为前缀来创建新的实例。当使用关键字来调用构造函数时,执行上下文从全局对象变成一个空的上下文,这个上下文代表了新生成的实例。默认情况下,如果构造函数中没有返回任何内容,就会返回当前的上下文。 公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。 JavaScr...

    caozhijian 评论0 收藏0
  • 和少妇白洁一起学JavaScript

    摘要:我们已经回答了的构造函数和原型都是谁的问题,现在牵扯出来一个,我们继续检查的构造函数是全局对象上属性叫的对象的原型是个匿名函数,按照关于构造函数的约定,它应该是构造函数的属性我们给这个对象起个名字,叫。 我不确定JavaScript语言是否应该被称为Object-Oriented,因为Object Oriented是一组语言特性、编程模式、和设计与工程方法的笼统称谓,没有一个详尽和大家...

    DevTTL 评论0 收藏0
  • JavaScript专题系列文章

    摘要:专题系列共计篇,主要研究日常开发中一些功能点的实现,比如防抖节流去重类型判断拷贝最值扁平柯里递归乱序排序等,特点是研究专题之函数组合专题系列第十六篇,讲解函数组合,并且使用柯里化和函数组合实现模式需求我们需要写一个函数,输入,返回。 JavaScript 专题之从零实现 jQuery 的 extend JavaScritp 专题系列第七篇,讲解如何从零实现一个 jQuery 的 ext...

    Maxiye 评论0 收藏0

发表评论

0条评论

Nekron

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<