Array of objects handler
To answer your specific concern about jQuery-dependence, the jQuery extend function is basically this:

var key;
for(key in objB) {
  objA[key] = objB[key]; // copy each value from objB into objA
}


That's all there is to it really.

However, I see a number of other things in your code that I think deserve attention.

1. Why define pluck insides the AOHandler constructor, and everything else in its prototype? Just wondering, since it's an unnecessary mixing of style. pluck can just as easily go in the prototype.

2. You're using typeof ao === 'object' when determining whether to use the argument passed to the constructor or not. Use ao instanceof Array instead. Almost everything in JS is "typeof object", but what you're looking for is an array and only an array. (I'd probably be strict about it too and throw an exception if a non-array argument is passed).

3. Your code doesn't seem to handle multiple identical values very well. Say I do this:

var ao = new AOHandler(),
    obj = { foo: "bar" },
    dup = $.extend({}, obj);

ao.add(obj);
ao.add(dup);
ao.add(obj);


Now there are three items in the AOHandler's list, two of which are the exact same object, and the third being a copy. None of you functions seem prepared to deal with such a situation. For instance, calling update would update the first item, which happens to also be the third item, so in fact 2 items get updated. However, the 2nd item (which has the same values, but isn't the same object) would be untouched. Could get pretty confusing.

4. Your function names seems a little off to me. pluck usually means to pick out values from each item in a list (i.e. a map-like function); not the items themselves, and certainly not only the first one. filter, select, find, search, or fetch would all be better names, provided the function actually returns all the matches. filter is indeed the name used for the native JS function (available in ECMA 5) that, well, filters an array and return the subset that matches a comparison function.

However, your pluck can also return the index of an item. You call it key, but since this.ao is a normal numerically-indexed array index is the word to use. Key implies it won't change, but indices of an array do change when other items are added or removed.
Anyway, the usual JS name for a function that finds the index of a certain thing in an array is indexOf. So I'd suggest that you break the pluck function into an indexOf function and a filter function, since those are separate things.

You could also make the case for push instead of add, since AOHandler is pretty much a wrapper around an array, and you push items to arrays. But add is plain English (and the same that Java uses for its ArrayList), so it's fine to use.

update is more problematic though, because it really does 2 (very) different things: Merge or replace. Merge will update the object in-place, so whereever else you have a reference to it, the updates will be visible. Replacing the object is a different story altogether. Again, I'd suggest 2 functions, since the effects are so very different, and the implementations have little in common.

Here's me take:

function AOHandler(ao) {
  // if anything's passed, it must be an array
  if(typeof ao !== "undefined" &amp;&amp; !(ao instanceof Array)) {
    throw new TypeError;
  }
  this.ao = ao || [];
}

AOHandler.prototype.indexOf = function (predicate, offset) {
  var i, l = this.ao.length;
  if(typeof predicate !== 'object') { throw new TypeError; } // type check
  offset = parseInt(offset, 10) || 0;
  // match native indexOf's handling of negative offset
  // see: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
  offset = (offset &lt; 0 ? l - offset : offset);
  offset = offset &lt; 0 ? 0 : offset;
  for( i = offset ; i &lt; l ; i++ ) {
    if(this.ao[i][predicate.key] === this.ao[i][predicate.value]) {
      return i;
    }
  }
  return -1;
};

AOHandler.prototype.filter = function (predicate) {
  var offset = 0, index, results = [];
  while((index = this.indexOf(predicate, offset)) !== -1) {
    results.push(this.ao[index]);
    offset = index + 1;
  }
  return results;
};

// This, by the way, is a pluck function
AOHandler.prototype.pluck = function (key) {
  var i, l, results = [];
  for( i = 0, l = this.ao.length ; i &lt; l ; i++ ) {
    results.push(this.ao[i][key]);
  }
  return results;
};

AOHandler.prototype.add = function (obj) {
  if(typeof obj !== 'object') { throw new TypeError; } // type check
  return this.ao.push(obj);
};

AOHandler.prototype.get = function (predicate) {
  var index = this.indexof(predicate);
   // return null - not false - if no obj is found
  return (index === -1 ? null : this.ao[index]);
};

// Simple jQuery-less merge function
AOHandler.prototype.update = function (predicate, source) {
  var matches = this.filter(predicate), i, l, key;
  if(typeof source !== 'object') { throw new TypeError; } // type check
  for( i = 0, l = matches.length ; i &lt; l ; i++ ) {
    for(key in source) {
      // it may be a good idea to do a source.hasOwnProperty[key] check here
      matches[i][key] = source[key];
    }
  }
};

// replace all matches
AOHandler.prototype.replace = function (predicate, replacement) {
  var matches = this.filter(predicate), index, l, offset, key;
  if(typeof replacement !== 'object') { throw new TypeError; } // type check
  while((index = this.indexOf(predicate, offset)) !== -1) {
    this.ao[index] = replacement;
    offset = index + 1;
  }
};