function Cat (name, color) { return { name: name, color: color } } var cat1 = Cat("大毛", "黄色");//{name: "大毛", color: "黄色"} var cat2 = Cat("二毛", "黑色");//{name: "二毛", color: "黑色"}
这种模式并不能看出来 cat1 和 cat2 是同一个原型对象的实例css
构造函数模式html
function Cat (name, color) { this.name = name; this.color = color; this.age = "5"; } var cat1 = new Cat("大毛", "黄色"); var cat2 = new Cat("二毛", "黑色"); cat1.constructor == Cat;//true cat2.constructor == Cat; //true cat1.constructor == cat2.constructor//true
cat1 instanceof Cat ;// true
function Cat (name, color) { this.name = name; this.color = color; } Cat.prototype.age = "10"; var cat1 = new Cat("大毛", "黄色"); var cat2 = new Cat("二毛", "黑色"); cat1.age; // 10; cat2.age; // 10;
// 建立父构造函数 function SuperClass(name){ this.name = name; this.showName = function(){ alert(this.name); } } // 设置父构造器的原型对象 SuperClass.prototype.Age = '123'; // 建立子构造函数 function SubClass(){} // 设置子构造函数的原型对象实现继承 SubClass.prototype = SuperClass.prototype; //生成实例 var child = new SubClass() child.name // undefined child.Age // 123
//即 子构造函数.prototype = new 父构造函数() // 建立父构造函数 function SuperClass(){ this.name = 'HiSen'; this.age = 25; this.showName = function(){ console.log(this.name); } } // 设置父构造函数的原型 SuperClass.prototype.friends = ['js', 'css']; SuperClass.prototype.showAge = function(){ console.log(this.age); } // 建立子构造函数 function SubClass(){} // 实现继承 SubClass.prototype = new SuperClass(); // 修改子构造函数的原型的构造器属性,由于此时继承了父构造函数指向 //SuperClass; 因此要修改一下。 SubClass.prototype.constructor = SubClass; //生成实例 var child = new SubClass();
console.log(child.name); // HiSen console.log(child.age);// 25 child.showName();// HiSen child.showAge();// 25 console.log(child.friends); // ['js','css'] // 当咱们改变friends的时候, 父构造函数的原型对象的也会变化 child.friends.push('html'); console.log(child.friends);// ["js", "css", "html"] var father = new SuperClass(); console.log(father.friends);// ["js", "css", "html"]
此时再看:发现子构造函数 不只继承了父构造函数原型 prototype 上的成员,也继承了其它成员。但是修改子构造函数的属性时,咱们发现父构造函数的原型对象也对应修改,那有没有办法屏蔽这一种状况呢 ? 接着往下看:数组
拷贝实现继承函数
说到拷贝,可能会分深拷贝和浅拷贝,其实:this
浅拷贝是对象的属性的引用,而不是对象自己; (浅拷贝只拷贝一层,若是存在多层仍是会影响原对象)spa
深拷贝是建立一个新的内存地址保存值 ; (与原对象互不影响)prototype
下边我列举两个拷贝的方法来实践一下:code
浅拷贝htm
例举一个简单的浅拷贝: 对象形式对象
function clone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { target[i] = source[i]; } } return target; }
深拷贝
对象形式的深拷贝
function clone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { if (typeof source[i] === 'object') { target[i] = clone(source[i]); // 注意这里 } else { target[i] = source[i]; } } } return target; }
数组形式的深拷贝
function clone(source) { var out = [],i = 0,len = source.length; for (; i < len; i++) { if (source[i] instanceof Array){ out[i] = clone(arr[i]); } else out[i] = source[i]; } return out; }
固然出了以上这些实现继承的方法之外还有更多的方式一样能够实现继承,例如:
Object.create();继承
Object.defineProperties()
的第二个参数同样)。注意:该参数对象不能是
undefined
,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。
var obj = {
"a":'123', fun :function () { alert(1) } }
var jc = Object.create(obj); jc.a; //123 jc.fun();//1
咱们能够看到,jc 继承了 obj 的属性;同时也继承了 obj 对象的方法;
ES6钟提供了一个方法 Object.assign();
方法能够把任意多个的源对象自身的可枚举属性拷贝给目标对象,而后返回目标对象。Object.assign
是ES6的新函数。Object.assign()
Object.assign(target, ...sources)
target:目标对象。
sources:任意多个源对象。
var obj = { a: {a: "hello", b: 21} }; var initalObj = Object.assign({}, obj); initalObj.a.a = "changed"; console.log(obj.a.a); // "changed"
最后再说一种最简单的方式,转成字符串 - 再转回来;
var obj1 = { o: { a: 1 } }; var obj2 = JSON.parse(JSON.stringify(obj1));