• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • jQuery.extend()

    将两个或更多对象的内容合并到第一个对象。

    jQuery.extend(target[, object1 ][, objectN ])
    • target类型: Object。一个对象,如果附加的对象被传递给这个方法将那么它将接收新的属性,如果它是唯一的参数将扩展jQuery的命名空间。
    • object1类型: Object。一个对象,它包含额外的属性合并到第一个参数
    • objectN类型: Object。包含额外的属性合并到第一个参数
    仅一个参数如果只有一个参数提供给$.extend(),这意味着目标参数被省略。在这种情况下,jQuery对象本身被默认为目标对象。这样,我们可以在jQuery的命名空间下添加新的功能。这对于插件开发者希望向 jQuery 中添加新函数时是很有用的。
    多个参数当我们提供两个或多个对象给$.extend(),对象的所有属性都添加到目标对象(target参数)。目标对象(第一个参数)将被修改,并且将通过$.extend()返回。然而,如果我们想保留原对象,我们可以通过传递一个空对象作为目标对象:var object =$.extend({}, object1, object2);。在默认情况下,通过$.extend()合并操作不是递归的;如果第一个对象的属性本身是一个对象或数组,那么它将完全被第二个对象相同的key重写。这些值不会被合并。
    jQuery.extend([deep ], target, object1[, objectN ])
    • deep类型: Boolean。如果是 true,合并成为递归(又叫做深拷贝)。不支持给这个参数传递false
    • target类型: Object。对象扩展。这将接收新的属性。
    • object1类型: Object。一个对象,它包含额外的属性合并到第一个参数.
    • objectN类型: Object。包含额外的属性合并到第一个参数
    默认不是递归合并。如果第一个对象的属性本身是一个对象或数组,那么它将完全被第二个对象相同的key重写。这些值不会被合并。
    deep设为true如果将true作为该函数的第一个参数,那么会在对象上进行递归合并。未定义的属性不会被复制。但是,从对象的原型继承属性将被复制。通过new MyCustomObject(args)或内置JavaScript类型(例如Date或RegExp)构造的对象的属性不会重新构造,并在结果对象或数组中显示为纯对象。(警告:不支持第一个参数传递false。)
    在deep某种程度上,对象和数组得到了扩展,但原始类型(如String,Boolean和Number)上的对象包装没有被扩展。深度扩展循环数据结构将导致错误。

    若要满足其它不同于该行为的需求,编写自定义的扩展方法代替。或者使用其他库,比如lodash。


    警告jQuery3.4之前的版本存在一个安全问题,即调用jQuery.extend(true,{}, object)包含__proto__属性的未过滤对象会扩展Object.prototype。

    例子

    合并两个对象,并修改第一个对象。

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>jQuery.extend demo</title>
      <script src="https://www.lanmper.cn/static/js/jquery-3.5.0.js"></script>
    </head>
    <body>
     
    <div id="log"></div>
     
    <script>
    var object1 = {
      apple: 0,
      banana: { weight: 52, price: 100 },
      cherry: 97
    };
    var object2 = {
      banana: { price: 200 },
      durian: 100
    };
     
    // Merge object2 into object1
    $.extend( object1, object2 );
     
    // Assuming JSON.stringify - not available in IE<8
    $( "#log" ).append( JSON.stringify( object1 ) );
    </script>
     
    </body>
    </html>
    

    采用递归方式合并两个对象,并修改第一个对象。

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>jQuery.extend demo</title>
      <script src="https://www.lanmper.cn/static/js/jquery-3.5.0.js"></script>
    </head>
    <body>
     
    <div id="log"></div>
     
    <script>
    var object1 = {
      apple: 0,
      banana: { weight: 52, price: 100 },
      cherry: 97
    };
    var object2 = {
      banana: { price: 200 },
      durian: 100
    };
     
    // Merge object2 into object1, recursively
    $.extend( true, object1, object2 );
     
    // Assuming JSON.stringify - not available in IE<8
    $( "#log" ).append( JSON.stringify( object1 ) );
    </script>
     
    </body>
    </html>
    

    合并 defaults 和 options 对象,并且不修改 defaults 对象。这是常用的插件开发模式。

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>jQuery.extend demo</title>
      <script src="https://www.lanmper.cn/static/js/jquery-3.5.0.js"></script>
    </head>
    <body>
     
    <div id="log"></div>
     
    <script>
    var defaults = { validate: false, limit: 5, name: "foo" };
    var options = { validate: true, name: "bar" ,null:"dee",title:""};
     
    // Merge defaults and options, without modifying defaults
    var settings = $.extend( {}, defaults, options );
     
    // Assuming JSON.stringify - not available in IE<8
    $( "#log" ).append( "<div><b>defaults -- </b>" + JSON.stringify( defaults ) + "</div>" );
    $( "#log" ).append( "<div><b>options -- </b>" + JSON.stringify( options ) + "</div>" );
    $( "#log" ).append( "<div><b>settings -- </b>" + JSON.stringify( settings ) + "</div>" );
    </script>
     
    </body>
    </html>
    

    深浅拷贝

    深浅拷贝对应的参数就是[deep],是可选的,为truefalse。默认情况是false(浅拷贝),并且false是不能够显示的写出来的。如果想写,只能写true(深拷贝)

    • 在默认情况下,通过$.extend()合并操作不是递归的(浅拷贝);如果第一个对象的属性本身是一个对象或数组,那么它将完全用第二个对象相同的key重写一个属性。这些值不会被合并。然而,如果将 true 作为该函数的第一个参数,那么会在对象上进行递归的合并(深拷贝)。
    • 浅拷贝(false 默认):如果第二个参数对象有的属性第一个参数对象也有,那么不会进行相同参数内部的比较,直接将第一个对象的相同参数覆盖。
    • 深拷贝(true):如果第二个参数对象有的属性第一个参数对象也有,还要继续在这个相同的参数向下一层找,比较相同参数的对象中是否还有不一样的属性,如果有,将其继承到第一个对象,如果没有,则覆盖。
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Dialog插件测试页面</title>
        <script type="text/javascript" src="jquery.js"></script>
    <script>
    var object1 = {
        apple: 0,
        banana: {
            weight: 52,
            price: 100
        },
        cherry: 97
    };
    var object2 = {
        banana: {
            price: 200
        },
        durian: 100
    };
     
    //默认情况浅拷贝
    //object1--->{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
    //object2的banner覆盖了object1的banner,但是weight属性未被继承
    //$.extend(object1, object2);
     
    //深拷贝
    //object1--->{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
    //object2的banner覆盖了object1的banner,但是weight属性也被继承了呦
    $.extend(true,object1, object2);
     
    console.log('object1--->'+JSON.stringify(object1));
    </script>
    </head>
    <body>
     
    </body>
    </html>