获取对象 obj 的所有属性(自有属性和继承属性),保存到数组 lst 中
1 //获取对象obj的所有属性(自有属性和继承属性),保存到数组lst 中 2 var lst = []; 3 function getAllAttrs(obj){ 4 var arr = Object.getOwnPropertyNames(obj); 5 for(r in arr){ 6 lst.push(arr[r]); 7 } 8 if(obj.__proto__ !== null){ 9 obj = obj.__proto__; 10 getAllAttrs(obj); 11 } 12 } 13 getAllAttrs(obj); 14 console.log(lst);
实现一个完整的复数类
1 //实现一个完整的复数类: Complex 2 3 //定义构造函数 4 function Complex(real, imaginary){ 5 if(isNaN(real) || isNaN(imaginary)) throw TypeError(); 6 this.r = real; 7 this.i = imaginary; 8 }; 9 // 定义非静态方法 10 Complex.prototype.add = function(that){ 11 return new Complex(this.r+that.r,this.i+that.i); 12 }; 13 Complex.prototype.mui = function(that){ 14 return new Complex(this.r*that.r-this.i*that.i,this.r*that.r+this.i*that.i); 15 }; 16 //取模运算 17 Complex.prototype.mag = function(){ 18 return Math.sqrt(this.r*this.r+this.i*this.i); 19 }; 20 Complex.prototype.neg = function(){ 21 return new Complex(-this.r,-this.i); 22 }; 23 Complex.prototype.toString = function(){ 24 return "{"+this.r+", "+this.i+"}"; 25 }; 26 Complex.prototype.equals = function(that){ 27 return that != null && 28 that.constructor === Complex && 29 this.r === that.r && 30 this.i === that.i; 31 }; 32 //定义类静态属性 33 Complex.ZERO = new Complex(0,0); 34 Complex.ONE = new Complex(1,0); 35 Complex.I = new Complex(0,1); 36 //定义类静态方法 37 Complex.parse = function(s){ 38 try{ 39 var m = Complex._format.exec(s); 40 return new Complex(parseFloat(m[1]),parseFloat(m[2])); 41 }catch(x){ 42 throw new TypeError("Can‘t parse "+s+" as a complex number."); 43 } 44 }; 45 //静态类属性 46 Complex._format = /^\{([^,]+),([^}]+)\}$/; 47 48 //使用 49 var c = new Complex(2,3); 50 var d = new Complex(c.i,c.r); 51 console.log(c.add(d).toString()); // {5, 5} 52 console.log(Complex.parse(c.toString())); // Complex {r: 2, i: 3} 53 console.log(Complex.parse(c.toString()).add(c.neg()).equals(Complex.ZERO)); // true
判断鸭辩型
1 //判断鸭辩型 2 //如果 o 实现了除第一个参数之外的参数所表示的同名方法, 则返回true 3 function quacks3(o){ 4 for(var i=1;i<arguments.length;++i){//遍历o之后的所有参数 5 var arg = arguments[i]; 6 switch(typeof arg){ 7 case ‘string‘: // 参数为string直接用名字检查 8 if(typeof o[arg] !== "function") 9 return false; 10 continue; 11 case ‘function‘: // 参数为函数, 视为构造函数, 检查函数的原型对象上的方法 12 arg = arg.prototype; //进入下一个case 13 case ‘object‘: 14 for(var m in arg){ //遍历对象的每个属性 15 if(typeof arg[m] !== ‘function‘) //跳过不是方法的属性 16 continue; 17 if(typeof o[m] !== ‘function‘) 18 return false; 19 } 20 21 } 22 } 23 return true; 24 } 25 //说明: 只检测函数名,而不用管细节, 不是强制的API,因此满足鸭辩型的本质, 灵活 26 //限制: 不能用于内置类, 因为for/in不能遍历不可枚举的方法. 在ES5中可以使用Object.getOwnPropertyNames() 27 function quacks5(o){ 28 for(var i=1;i<arguments.length;++i){ 29 var arg = arguments[i]; 30 switch(typeof arg){ 31 case ‘string‘: 32 if(typeof o[arg] !== ‘function‘) 33 return false; 34 continue; 35 case ‘function‘: 36 arg = arg.prototype; 37 case ‘object‘: 38 var props = Object.getOwnPropertyNames(arg.__proto__); 39 var props2 = Object.getOwnPropertyNames(arg); 40 for(var prop in props2){ 41 props.push(props2[prop]); 42 } 43 for(var m in props){ 44 if(props[m] !== ‘function‘) 45 continue; 46 if(o[m] !== ‘function‘) 47 return false; 48 } 49 } 50 } 51 return true; 52 };
合并多个对象属性
1 // 将变长参数sources对象的可枚举(for/in)属性合并到target中,并返回target 2 // target 的值是被修改的, 深拷贝(递归合并) 3 // 合并从左到右进行, 同名属性保持和左边一样(除非属性是空对象) 4 function myextend(target /*...sources*/){ 5 if(!arguments.length) 6 return undefined; 7 if(arguments.length === 1) 8 return target; 9 for(var i=1;i<arguments.length;++i){ 10 var source = arguments[i]; 11 for(var prop in source){ 12 if(target.hasOwnProperty(prop) && 13 target[prop] !== undefined && 14 target[prop] != {}) // 目标对象上该属性存在且属性值不为undefined(可以为null)且不为空对象 15 continue; 16 if(typeof source[prop] === ‘object‘){ 17 target[prop] = {}; 18 target[prop] = myextend({},source[prop]); 19 }else{ 20 target[prop] = source[prop]; 21 } 22 } 23 } 24 return target; 25 }
测试:
1 // 结果在chrome console中查看 2 var target = { 3 t1:1, 4 t2:{ 5 t1:1, 6 t2:{ 7 t1:1, 8 t2:"t2" 9 } 10 } 11 }; 12 var source1 = { 13 s1:2, 14 s2:{ 15 s1:2, 16 s2:{ 17 s1:2, 18 s2:"s2" 19 } 20 } 21 }; 22 var source2 = { 23 r1:3, 24 r2:{ 25 r1:3, 26 s2:{ 27 r1:3, 28 r2:"s2" 29 } 30 } 31 }; 32 var t = myextend(target,source1,source2); 33 console.log(t);
持续更新中...
参考
1. <<JavaScript权威指南: 第6版>>
时间: 2024-11-12 00:05:43