mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 02:47:50 +00:00
Ensure clone methods create maps and sets from other realms.
This commit is contained in:
92
lodash.js
92
lodash.js
@@ -976,28 +976,6 @@
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a map from key-value `pairs`.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} pairs The key-value pairs to add.
|
|
||||||
* @returns {Object} Returns the new map.
|
|
||||||
*/
|
|
||||||
function createMap(pairs) {
|
|
||||||
return arrayReduce(pairs, addMapEntry, new Map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a set from `values`.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} values The values to add.
|
|
||||||
* @returns {Object} Returns the new set.
|
|
||||||
*/
|
|
||||||
function createSet(values) {
|
|
||||||
return arrayReduce(values, addSetEntry, new Set);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
|
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
|
||||||
*
|
*
|
||||||
@@ -3113,20 +3091,75 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clone of the given array buffer.
|
* Creates a clone of `buffer`.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {ArrayBuffer} buffer The array buffer to clone.
|
* @param {ArrayBuffer} buffer The array buffer to clone.
|
||||||
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
||||||
*/
|
*/
|
||||||
function cloneBuffer(buffer) {
|
function cloneBuffer(buffer) {
|
||||||
var result = new ArrayBuffer(buffer.byteLength),
|
var Ctor = buffer.constructor,
|
||||||
|
result = new Ctor(buffer.byteLength),
|
||||||
view = new Uint8Array(result);
|
view = new Uint8Array(result);
|
||||||
|
|
||||||
view.set(new Uint8Array(buffer));
|
view.set(new Uint8Array(buffer));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a clone of `map`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} map The map to clone.
|
||||||
|
* @returns {Object} Returns the cloned map.
|
||||||
|
*/
|
||||||
|
function cloneMap(map) {
|
||||||
|
var Ctor = map.constructor;
|
||||||
|
return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a clone of `regexp`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} regexp The regexp to clone.
|
||||||
|
* @returns {Object} Returns the cloned regexp.
|
||||||
|
*/
|
||||||
|
function cloneRegExp(regexp) {
|
||||||
|
var Ctor = regexp.constructor,
|
||||||
|
result = new Ctor(regexp.source, reFlags.exec(regexp));
|
||||||
|
|
||||||
|
result.lastIndex = regexp.lastIndex;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a clone of `set`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} set The set to clone.
|
||||||
|
* @returns {Object} Returns the cloned set.
|
||||||
|
*/
|
||||||
|
function cloneSet(set) {
|
||||||
|
var Ctor = set.constructor;
|
||||||
|
return arrayReduce(setToArray(set), addSetEntry, new Ctor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a clone of `typedArray`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} typedArray The typed array to clone.
|
||||||
|
* @param {boolean} [isDeep] Specify a deep clone.
|
||||||
|
* @returns {Object} Returns the cloned typed array.
|
||||||
|
*/
|
||||||
|
function cloneTypedArray(typedArray, isDeep) {
|
||||||
|
var buffer = typedArray.buffer,
|
||||||
|
Ctor = typedArray.constructor;
|
||||||
|
|
||||||
|
return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an array that is the composition of partially applied arguments,
|
* Creates an array that is the composition of partially applied arguments,
|
||||||
* placeholders, and provided arguments into a single array of arguments.
|
* placeholders, and provided arguments into a single array of arguments.
|
||||||
@@ -4088,24 +4121,21 @@
|
|||||||
case float32Tag: case float64Tag:
|
case float32Tag: case float64Tag:
|
||||||
case int8Tag: case int16Tag: case int32Tag:
|
case int8Tag: case int16Tag: case int32Tag:
|
||||||
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
||||||
var buffer = object.buffer;
|
return cloneTypedArray(object, isDeep);
|
||||||
return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, object.byteOffset, object.length);
|
|
||||||
|
|
||||||
case mapTag:
|
case mapTag:
|
||||||
return createMap(mapToArray(object));
|
return cloneMap(object);
|
||||||
|
|
||||||
case numberTag:
|
case numberTag:
|
||||||
case stringTag:
|
case stringTag:
|
||||||
return new Ctor(object);
|
return new Ctor(object);
|
||||||
|
|
||||||
case setTag:
|
case setTag:
|
||||||
return createSet(setToArray(object));
|
return cloneSet(object);
|
||||||
|
|
||||||
case regexpTag:
|
case regexpTag:
|
||||||
var result = new Ctor(object.source, reFlags.exec(object));
|
return cloneRegExp(object);
|
||||||
result.lastIndex = object.lastIndex;
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
41
test/test.js
41
test/test.js
@@ -449,24 +449,29 @@
|
|||||||
_.attempt(function() {
|
_.attempt(function() {
|
||||||
_.extend(_, require('vm').runInNewContext([
|
_.extend(_, require('vm').runInNewContext([
|
||||||
'(function() {',
|
'(function() {',
|
||||||
' var object = {',
|
' var root = this;',
|
||||||
" '_arguments': (function() { return arguments; }(1, 2, 3)),",
|
'',
|
||||||
" '_array': [1, 2, 3],",
|
' var object = {',
|
||||||
" '_boolean': Object(false),",
|
" '_arguments': (function() { return arguments; }(1, 2, 3)),",
|
||||||
" '_date': new Date,",
|
" '_array': [1, 2, 3],",
|
||||||
" '_errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
|
" '_arrayBuffer': new (this.ArrayByffer || Object),",
|
||||||
" '_function': function() {},",
|
" '_boolean': Object(false),",
|
||||||
" '_nan': NaN,",
|
" '_date': new Date,",
|
||||||
" '_null': null,",
|
" '_errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
|
||||||
" '_number': Object(0),",
|
" '_function': function() {},",
|
||||||
" '_object': { 'a': 1, 'b': 2, 'c': 3 },",
|
" '_map': new (root.Map || Object),",
|
||||||
" '_regexp': /x/,",
|
" '_nan': NaN,",
|
||||||
" '_string': Object('a'),",
|
" '_null': null,",
|
||||||
" '_undefined': undefined",
|
" '_number': Object(0),",
|
||||||
|
" '_object': { 'a': 1, 'b': 2, 'c': 3 },",
|
||||||
|
" '_regexp': /x/,",
|
||||||
|
" '_set': new (root.Set || Object),",
|
||||||
|
" '_string': Object('a'),",
|
||||||
|
" '_undefined': undefined",
|
||||||
' };',
|
' };',
|
||||||
'',
|
'',
|
||||||
" ['" + typedArrays.join("', '") + "'].forEach(function(type) {",
|
" ['" + typedArrays.join("', '") + "'].forEach(function(type) {",
|
||||||
" var Ctor = Function('return typeof ' + type + \" != 'undefined' && \" + type)()",
|
" var Ctor = root[type]",
|
||||||
' if (Ctor) {',
|
' if (Ctor) {',
|
||||||
" object['_' + type.toLowerCase()] = new Ctor(new ArrayBuffer(24));",
|
" object['_' + type.toLowerCase()] = new Ctor(new ArrayBuffer(24));",
|
||||||
' }',
|
' }',
|
||||||
@@ -486,22 +491,26 @@
|
|||||||
var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
|
var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
|
||||||
idoc.write([
|
idoc.write([
|
||||||
'<script>',
|
'<script>',
|
||||||
|
'var root = this;',
|
||||||
|
'',
|
||||||
'parent._._arguments = (function() { return arguments; }(1, 2, 3));',
|
'parent._._arguments = (function() { return arguments; }(1, 2, 3));',
|
||||||
'parent._._array = [1, 2, 3];',
|
'parent._._array = [1, 2, 3];',
|
||||||
|
'parent._._arrayBuffer = new (this.ArrayByffer || Object);',
|
||||||
'parent._._boolean = Object(false);',
|
'parent._._boolean = Object(false);',
|
||||||
'parent._._date = new Date;',
|
'parent._._date = new Date;',
|
||||||
"parent._._element = document.createElement('div');",
|
"parent._._element = document.createElement('div');",
|
||||||
'parent._._errors = [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError];',
|
'parent._._errors = [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError];',
|
||||||
'parent._._function = function() {};',
|
'parent._._function = function() {};',
|
||||||
|
'parent._._map = new (this.Map || Object);',
|
||||||
'parent._._nan = NaN;',
|
'parent._._nan = NaN;',
|
||||||
'parent._._null = null;',
|
'parent._._null = null;',
|
||||||
'parent._._number = Object(0);',
|
'parent._._number = Object(0);',
|
||||||
"parent._._object = { 'a': 1, 'b': 2, 'c': 3 };",
|
"parent._._object = { 'a': 1, 'b': 2, 'c': 3 };",
|
||||||
'parent._._regexp = /x/;',
|
'parent._._regexp = /x/;',
|
||||||
|
'parent._._set = new (this.Set || Object);',
|
||||||
"parent._._string = Object('a');",
|
"parent._._string = Object('a');",
|
||||||
'parent._._undefined = undefined;',
|
'parent._._undefined = undefined;',
|
||||||
'',
|
'',
|
||||||
'var root = this;',
|
|
||||||
"parent._.each(['" + typedArrays.join("', '") + "'], function(type) {",
|
"parent._.each(['" + typedArrays.join("', '") + "'], function(type) {",
|
||||||
' var Ctor = root[type];',
|
' var Ctor = root[type];',
|
||||||
' if (Ctor) {',
|
' if (Ctor) {',
|
||||||
|
|||||||
Reference in New Issue
Block a user