2012-09-07 64 views
12

Tôi đang tìm kiếm một cách để hợp nhất hai cấu hình các đối tượng với nhau, một cái gì đó như:Một cái gì đó như jQuery.extend() nhưng độc lập?

var developmentConfig = { 
    url: "localhost", 
    port: 80 
}; 

var productionConfig = { 
    url: "example.com" 
}; 

var config = isDevelopment ? developmentConfig : jQuery.extend(developmentConfig, productionConfig); 

Tuy nhiên, đây là một ứng dụng Node.js và tôi không muốn bao gồm jQuery và đang tìm kiếm một cái gì đó tương tự nhưng độc lập. Tôi biết tôi có thể viết một cái gì đó tương tự như bản thân mình nhưng tôi muốn sử dụng một cái gì đó được thử nghiệm và chứng minh (có những trường hợp cạnh, các biến chứng khi các đối tượng cấu hình sử dụng phân cấp phong phú hơn, vv)

Sửa: Đơn giản lặp là không đủ bởi vì đó không xử lý cấu trúc phân cấp. Không phải của Underscore là extend.

+4

sử dụng nguồn, luke :) – epoch

+2

Có một trang web mà thực sự giúp với việc kiểm tra nguồn của jQuery. Đối với 'jQuery.extend', [ở đây bạn đi] (http://james.padolsey.com/jquery/#v=git&fn=jQuery.extend). –

+1

Tôi đã có một cái nhìn trước khi hỏi nhưng có những phụ thuộc bên ngoài từ hàm extend() để có nhiều việc phải làm hơn là chỉ sao chép một vài dòng. – Borek

Trả lời

18

Nếu tất cả những gì bạn cần là mở rộng, sau đó nó khá đơn giản để viết rằng trong một vài dòng. Nếu bạn muốn mở rộng đệ quy, đó là khó khăn để làm điều đó hoàn toàn quát nếu bạn muốn có cấu trúc tròn, đối tượng với chuỗi nguyên mẫu phức tạp, vv Nếu nó chỉ là một số đối tượng đồng bằng lồng nhau, thì điều này sẽ làm việc:

function extend (target, source) { 
    target = target || {}; 
    for (var prop in source) { 
    if (typeof source[prop] === 'object') { 
     target[prop] = extend(target[prop], source[prop]); 
    } else { 
     target[prop] = source[prop]; 
    } 
    } 
    return target; 
} 

Nếu bạn đang tìm kiếm một thư viện nhẹ thực hiện điều này (trừ đi đệ quy, vì những lý do được liệt kê ở trên) và các chức năng tương tự khác không được cung cấp bởi javascript, xem Underscore có sẵn thông qua NPM cho nút.

+0

Tôi cũng cần hành vi đệ quy, xem câu hỏi. – Borek

+0

@Borek Tôi đã cập nhật câu trả lời ngay bây giờ – nickf

+3

điều này cũng sẽ chuyển đổi mảng của bạn thành các đối tượng. –

4

Một ví dụ nhiều chức năng độc lập đơn giản cho những người hành hương trong tương lai qua câu hỏi này với bảo vệ từ hợp nhất của các thuộc tính của các loại khác nhau:

function extend(obj) { 
    Array.prototype.slice.call(arguments, 1).forEach(function(source) { 
     if (source) { 
      for (var prop in source) { 
       if (source[prop].constructor === Object) { 
        if (!obj[prop] || obj[prop].constructor === Object) { 
         obj[prop] = obj[prop] || {}; 
         extend(obj[prop], source[prop]); 
        } else { 
         obj[prop] = source[prop]; 
        } 
       } else { 
        obj[prop] = source[prop]; 
       } 
      } 
     } 
    }); 
    return obj; 
} 

Cách sử dụng:

extend({ name:'Maria', address:{ city:'Moscow', street:'Lenina str, 52' } }, { name:'Marianna', address:{ zip:1200003 }}) 
=> { name:'Marianna', address:{ city:'Moscow', street:'Lenina str, 52', zip:1200003 } } 
+0

đầu tiên "if" in "for": source [prop]! == null && source [prop] .constructor === Object –

1

Giải pháp này tạo ra một mới đối tượng và có thể xử lý nhiều đối tượng.

Hơn nữa, nó là đệ quy và bạn có thể chọn thời tiết bạn muốn để ghi đè Values ​​Objects.

function extendObjects() { 

     var newObject  = {}; 
     var overwriteValues = false; 
     var overwriteObjects = false; 

     for (var indexArgument = 0; indexArgument < arguments.length; indexArgument++) { 

      if (typeof arguments[indexArgument] !== 'object') { 

       if (arguments[indexArgument] == 'overwriteValues_True') { 

        overwriteValues = true;    
       } else if (arguments[indexArgument] == 'overwriteValues_False') { 

        overwriteValues = false;        
       } else if (arguments[indexArgument] == 'overwriteObjects_True') { 

        overwriteObjects = true;  
       } else if (arguments[indexArgument] == 'overwriteObjects_False') { 

        overwriteObjects = false; 
       } 

      } else { 

       extendObject(arguments[indexArgument], newObject, overwriteValues, overwriteObjects); 
      } 

     } 

     function extendObject(object, extendedObject, overwriteValues, overwriteObjects) { 

      for (var indexObject in object) { 

       if (typeof object[indexObject] === 'object') { 

        if (typeof extendedObject[indexObject] === "undefined" || overwriteObjects) { 
         extendedObject[indexObject] = object[indexObject]; 
        } 

        extendObject(object[indexObject], extendedObject[indexObject], overwriteValues, overwriteObjects); 

       } else { 

        if (typeof extendedObject[indexObject] === "undefined" || overwriteValues) { 
         extendedObject[indexObject] = object[indexObject]; 
        } 

       } 

      }  

      return extendedObject; 

     } 

     return newObject; 
    } 

    var object1   = { a : 1, b : 2, testArr : [888, { innArr : 1 }, 777 ], data : { e : 12, c : { lol : 1 }, rofl : { O : 3 } } }; 
    var object2   = { a : 6, b : 9, data : { a : 17, b : 18, e : 13, rofl : { O : 99, copter : { mao : 1 } } }, hexa : { tetra : 66 } }; 
    var object3   = { f : 13, g : 666, a : 333, data : { c : { xD : 45 } }, testArr : [888, { innArr : 3 }, 555 ] }; 

    var newExtendedObject = extendObjects('overwriteValues_False', 'overwriteObjects_False', object1, object2, object3); 

Nội dung newExtendedObject:

{"a":1,"b":2,"testArr":[888,{"innArr":1},777],"data":{"e":12,"c":{"lol":1,"xD":45},"rofl":{"O":3,"copter":{"mao":1}},"a":17,"b":18},"hexa":{"tetra":66},"f":13,"g":666} 

Fiddle: http://jsfiddle.net/o0gb2umb/

Các vấn đề liên quan