underscore源碼解析(object)

//用來變對象的。能夠沒有value直接傳list,把list變一個對象
//也能夠傳長度和list同樣的value,來構成數組
_.object = function(list, values) {
var result = {};
for (var i = 0, length = list && list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
result[list[i][0]] = list[i][1];
}
}
return result;
};

//獲取對象的全部鍵集合,有原生的nativeKeys,就用原生。
//貌似ie9如下有個枚舉bug,實例的toString會覆蓋原型上的toString,toString就變成不可枚舉了,都沒試出來過。。。。
//!({toString: null}).propertyIsEnumerable('toString');
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};


// 全部鍵列出來,實例和原型的
_.allKeys = function(obj) {
if (!_.isObject(obj)) return [];
var keys = [];
for (var key in obj) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};

// 實例鍵的值組成一個數組
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};

//相似map,只不過obj是對象,用iteratee迭代每一個鍵值對,返回新數組
_.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = _.keys(obj),
length = keys.length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys[index];
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};

//把一個對象轉變爲一個[key, value]形式的數組。
_.pairs = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var pairs = Array(length);
for (var i = 0; i < length; i++) {
pairs[i] = [keys[i], obj[keys[i]]];
}
return pairs;
};

// 對象鍵值對互換位置,要保證鍵值對中值的惟一性
_.invert = function(obj) {
var result = {};
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
result[obj[keys[i]]] = keys[i];
}
return result;
};
//把對象中的函數堆到一個數組中,函數名按字母a-z排序
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
//對象的擴展,擴展傳入的全部屬性,包括原型鏈
_.extend = createAssigner(_.allKeys);

////對象的擴展,擴展傳入的全部屬性,不包括原型鏈
_.extendOwn = _.assign = createAssigner(_.keys);

// Return a copy of the object only containing the whitelisted properties.
//返回obj,包含符合條件的鍵值對
_.pick = function(object, oiteratee, context) {
var result = {}, obj = object, iteratee, keys;
if (obj == null) return result;
if (_.isFunction(oiteratee)) {
keys = _.allKeys(obj);
iteratee = optimizeCb(oiteratee, context);
} else {
keys = flatten(arguments, false, false, 1);
iteratee = function(value, key, obj) { return key in obj; };
obj = Object(obj);
}
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = obj[key];
if (iteratee(value, key, obj)) result[key] = value;
}
return result;
};

// Return a copy of the object without the blacklisted properties.
//返回obj,過濾掉符合條件的鍵值對
_.omit = function(obj, iteratee, context) {
if (_.isFunction(iteratee)) {
iteratee = _.negate(iteratee);
} else {
var keys = _.map(flatten(arguments, false, false, 1), String);
iteratee = function(value, key) {
return !_.contains(keys, key);
};
}
return _.pick(obj, iteratee, context);
};

// Fill in a given object with default properties.
//對象擴展,對象的鍵是undefined的話就填充,不然就保留原來的
_.defaults = createAssigner(_.allKeys, true);

// Creates an object that inherits from the given prototype object.
// If additional properties are provided then they will be added to the
// created object.
_.create = function(prototype, props) {
var result = baseCreate(prototype);
if (props) _.extendOwn(result, props);
return result;
};

// Create a (shallow-cloned) duplicate of an object.
//克隆對象或數組
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};

// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
//調用interceptor,再傳慘obj。返回obj
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};

// Returns whether an object has a given set of `key:value` pairs.
//傳的鍵值對否在obj當中
_.isMatch = function(object, attrs) {
var keys = _.keys(attrs), length = keys.length;
if (object == null) return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = keys[i];
if (attrs[key] !== obj[key] || !(key in obj)) return false;
}
return true;
};


// Perform a deep comparison to check if two objects are equal.//2個對象是否相等_.isEqual = function(a, b) {    return eq(a, b);};// Is a given array, string, or object empty?// An "empty" object has no enumerable own-properties.//傳的東西是否爲空_.isEmpty = function(obj) {    if (obj == null) return true;    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;    return _.keys(obj).length === 0;};// Is a given value a DOM element?//是否是DOM元素_.isElement = function(obj) {    return !!(obj && obj.nodeType === 1);};// Is a given value an array?// Delegates to ECMA5's native Array.isArray//是否是數組_.isArray = nativeIsArray || function(obj) {        return toString.call(obj) === '[object Array]';    };// Is a given variable an object?//是否是對象_.isObject = function(obj) {    var type = typeof obj;    return type === 'function' || type === 'object' && !!obj;};// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.//對每一個原生類調用tostring方法,判斷是不是原生對象_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {    _['is' + name] = function(obj) {        return toString.call(obj) === '[object ' + name + ']';    };});// Define a fallback version of the method in browsers (ahem, IE < 9), where// there isn't any inspectable "Arguments" type.//參數對象有個callee屬性,指向函數自己,用來判斷是否是argumentsif (!_.isArguments(arguments)) {    _.isArguments = function(obj) {        return _.has(obj, 'callee');    };}// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,// IE 11 (#1621), and in Safari 8 (#1929).// 另外一種方法用Object.prototype.toString.call(obj)==='[object Function]';if (typeof /./ != 'function' && typeof Int8Array != 'object') {    _.isFunction = function(obj) {        return typeof obj == 'function' || false;    };}// Is a given object a finite number?_.isFinite = function(obj) {    return isFinite(obj) && !isNaN(parseFloat(obj));};// Is the given value `NaN`? (NaN is the only number which does not equal itself)._.isNaN = function(obj) {    return _.isNumber(obj) && obj !== +obj;};// Is a given value a boolean?_.isBoolean = function(obj) {    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';};// Is a given value equal to null?_.isNull = function(obj) {    return obj === null;};// Is a given variable undefined?_.isUndefined = function(obj) {    return obj === void 0;};// Shortcut function for checking if an object has a given property directly// on itself (in other words, not on a prototype).//http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/防止意外覆蓋原型上的方法_.has = function(obj, key) {    return obj != null && hasOwnProperty.call(obj, key);};
相關文章
相關標籤/搜索