From the comments, your motivation to bypass $(...).data seems to be based on the fact that it's causing performance issues.
I totally agree with @meagar on that point, $(...).data shouldn't be expensive enough to cause bottlenecks. However, if you continously re-query and re-wrap DOM elements as jQuery elements (e.g. $('#someEl').data(...) multiple times rather than caching $('#someEl') and do $someEl.data(...), then it might be an issue.
Please also note that if you find yourself attaching a lot of data to DOM elements, you probably got your design wrong. Your data shouldn't live in the presentation layer and you shouldn't have to query the DOM or get a reference to a DOM element to access your data. Obviously, you might in some situations, but these shouldn't be the norm.
If you still want to build your own data feature, then here's an example. It's not optimized, but you should get the idea:
Note that WeakMap is only available in modern browsers, but without it we would be leaking memory, unless you provide a mechanism to destroy the cached attributes expendo object when the associated DOM element gets destroyed.
JSFIDDLE
JSPERF (the test might not be fair, since I'm not sure my implementation does everyting $(...).data does)
var data = (function () {
var attributes = new WeakMap();
return function (el, attr, val) {
var elAttrs = attributes.get(el),
isSetOperation = arguments.length > 2;
if (isSetOperation) {
if (!elAttrs) attributes.set(el, elAttrs = {});
elAttrs[attr] = val;
} else {
return datasetOrCachedAttrsValue();
}
function datasetOrCachedAttrsValue() {
var attrVal = el.dataset[attr];
return typeof attrVal !== 'undefined'?
attrVal:
elAttrs && elAttrs[attr];
}
};
})();
var div = document.querySelector('div');
console.log(data(div, 'test')); //test
console.log(data(div, 'notexisting')); //undefined
data(div, 'exists', true);
console.log(data(div, 'exists')); //true
"would be leaking memory, unless you provide a mechanism to destroy the
cached" - plalx. Well even with WeakMap it still leaks for the same reason why
jQuery can cause leaks. See this demo. – dfsq
That was a good concern from @dfsq, but here's a demo that actually shows how WeakMap allows garbage collection once they key is unreachable, as opposed to jQuery's implementation that will hold on data (unless $().remove is used I believe).
Use the profiler and record heap allocations over time and compare the results. Here's what I got from 6 clicks on each button (one type of button per snapshot). We can clearly see that $().data is leaking while the custom data implementation using a WeakMap is not.
try to leak with $().data.

try to leak with data

data()setter is not stored in the DOM, but in an internal cache associated with the element. You would have to duplicate quite a lot of jQuery's implementation to retrieve that data in plain JS, and that implementation can change in the future, so I don't think this would be a good idea.$(...).dataway? It's like saying, you would like to use some API's features, but without going through that API. Pointless?dataother then via$.dataAPI. But if OP wants to know where jQuery stores those values, the answer is simple: event handlers and data are stored in$.cache.