var class2type = {}; var getProto = Object.getPrototypeOf; //获取构造函数的原型prototype var hasOwn = class2type.hasOwnProperty;//判断对象自身自身是否有属性 var fnToString = hasOwn.toString; //返回的结果以字符串的形式展示 var ObjectFunctionString = fnToString.call( Object ); function isPlainObject( obj ) { var proto, Ctor; //判断是不是一个对象 if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); console.log(proto) //没有原型的对象 比如`Object.create( null ) if ( !proto ) { return true; } Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; } //判断是不是一个数组 function isArray(arr) { return Object.prototype.toString.call(arr) === '[array Array]' } //判断是不是一个函数 var isFunction = function isFunction( obj ) { return typeof obj === "function" && typeof obj.nodeType !== "number"; }; function extend() { var target = arguments[0] || {}, length = arguments.length, i=1, options, name, src, copy, deep=false, clone, copyIsArray; //如果参数是第一个是boolean //如下情况 extend(true,obj1,obj2); if(typeof target === 'boolean'){ //互殴第一个参数,赋值给deep deep = target //标记为深拷贝 target = arguments[1] || {}; //获取第二个值 i++; //将循环的下标标记到第二个 } //处理特殊清理 extend('hello',{name:10}) if(typeof target !== 'object' && !isFunction(target)){ target = {} } //如果只有一个参数 extend(obj) if(i === length){ target = this; i--; } for (; i<length;i++){ if((options = arguments[i]) != null){ //获取每个对象的属性 for (name in options){ src = target[name] copy = options[name] //防止自引用 if(target === copy){ continue } //如果是深拷贝,而且拷贝的属性本身就是个对象 if(deep && copy && (isPlainObject(src) || (copyIsArray = isArray(src)))){ if(copyIsArray){ //被拷贝的值是个数组 copyIsArray = false clone = src && isArray(src) ? src : [] }else{ clone = src && isPlainObject(src) ? src : {} } target[name] = extend(depp,clone,copy) //递归调用 }else if(copy != undefined){//不拷贝undefine的值 target[name] = copy } } } } return target; }
JQ的extend方法解析
最新推荐文章于 2024-08-17 11:49:10 发布