Javascript 创建对象总结
2016-10-26 11:19
274 查看
使用JavaScript创建对象的方法有很多,现在就来列举一下。
能够把可以重用的部分迁移到原型链中,而不可重用的则设置为对象的自身属性。
对
一个致命缺点就是,无法修正子类构造的对象的 constructor。
构造器借用法应运而生。现在我们把 name 属性的创建还是交给 Animal,然后再为 Human 增加 country 属性。我们在“临时构造器法”基础上进一步完善之。
另外还有两个创建对象的方法,寄生构造函数模式和稳妥构造函数模式。由于这两个函数用得比较少。
1、使用Object构造函数来创建一个对象
下面代码创建了一个person对象,并打印出了
name的属性值。
var person = new Object(); person.name="Joe"; person.age=25; alert(person.name); alert(person["name"])
2、使用对象字面量创建一个对象
var person = { name:"Joe", age:25 }; alert(person.name); alert(person["name"]);
3、使用工厂模式创建对象
返回带有属性和方法的person对象。
function createPerson(name, age){ var o = new Object(); o.name=name; o.age=age; o.sayName=function(){ alert(this.name); }; return o; } var people=createPerson("kevin",31); people.sayName();
4、使用自定义构造函数模式创建对象
这里注意命名规范,作为构造函数的函数首字母要大写,以区别其它函数。这种方式有个缺陷是sayName这个方法,它的每个实例都是指向不同的函数实例,而不是同一个。
function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert(this.name); }; } var person = new Person("Joe",25); person.sayName();
5、使用原型模式创建对象
解决了方法4中提到的缺陷,使不同的对象的函数(如sayFriends)指向了同一个函数。但它本身也有缺陷,就是实例共享了引用类型
friends,从下面的代码执行结果可以看到,两个实例的
friends的值是一样的,这可能不是我们所期望的。
function Person(){ } Person.prototype = { constructor : Person, name:"Joe", age:25, friends:["Json","Jack"], sayFriends:function(){ alert(this.friends); } }; var person1 = new Person(); person1.friends.push("Ares");//这里把构造函数的原型给改了 person1.sayFriends();//Json,Jack,Ares var person2 = new Person(); person2.sayFriends();//Json,Jack,Ares
6、组合使用原型模式和构造函数创建对象
解决了方法5中提到的缺陷,而且这也是使用最广泛、认同度最高的创建对象的方法。能够把可以重用的部分迁移到原型链中,而不可重用的则设置为对象的自身属性。
function Person(name,age){ this.name=name; this.age=age; this.friends=["Json","Jack"]; } Person.prototype.sayFriends=function(){ alert(this.friends); }; var person1 = new Person("Andy",26); var person2 = new Person("Tom",27); person1.friends.push("Joe"); person1.sayFriends();//Json,Jack,Joe person2.sayFriends();//Json,Jack
7、仅从原型继承法
和“原型链继承法”相比,本方法的优点在于,提高了运行时的效率,没有创建新对象出来。对
Human.prototype的修改都会影响到
Animal.prototype,因为两者指向的是同一个对象。
一个致命缺点就是,无法修正子类构造的对象的 constructor。
var Animal = function(name){ this.name = name; }; Animal.prototype.jump = function(){ console.log('jumped'); }; var Human = function(name){ this.name = name; }; Human.prototype = Animal.prototype; var man = new Human('HaoyCn'); man.jump();
8、原型链继承法
var Animal = function(name){ this.name = name; }; Animal.prototype.jump = function(){ console.log('jumped'); }; var Human = function(name){ this.name = name; }; // 这一步会使得,Human.prototype.constructor = Animal,所以需要重新手动重定向。而且这里会产生一个undefied属性name,因为没有传入参数。 Human.prototype = new Animal; //如果不更改,通过`Human`构造器构造出来的对象的构造器会变成`Animal`而不是`Human` Human.prototype.constructor = Human; var man = new Human('HaoyCn'); man.jump();
9、临时构造器继承法
“临时构造器继承法”使用一个中介函数,避免了Animal.prototype会因对
Human.prototype的修改而改变,也避免了产生未定义的属性。
var Animal = function(name){ this.name = name; }; Animal.prototype.jump = function(){ console.log('jumped'); }; var F = function(){}; F.prototype = Animal.prototype; var Human = function(name){ this.name = name; }; Human.prototype = new F; Human.prototype.constructor = Human; Human.prototype.sing = function(){ console.log('Mayday'); }; var man = new Human('HaoyCn'); man.jump(); man.sing();
10、构造器借用法
以上继承法共通的一个缺点在于,Human构造器构造的对象虽然可以共用
Animal.prototype,但对于
name属性而言,
Human构造器只能自己再写一遍构造
name属性,为什么不把初始化属性的方法也共(借)用呢?
构造器借用法应运而生。现在我们把 name 属性的创建还是交给 Animal,然后再为 Human 增加 country 属性。我们在“临时构造器法”基础上进一步完善之。
var Animal = function(name){ this.name = name; }; Animal.prototype.jump = function(){ console.log('jumped'); }; var F = function(){}; F.prototype = Animal.prototype; var Human = function(){ Animal.apply(this,arguments); this.country = arguments[1]; } Human.prototype = new F; Human.prototype.constructor = Human; var man = new Human('HaoyCn','China'); console.log(man.country);// China
11、动态原型模式
这个模式的好处在于看起来更像传统的面向对象编程,具有更好的封装性,因为在构造函数里完成了对原型创建。这也是一个推荐的创建对象的方法。function Person(name,age){ //属性 this.name=name; this.age=age; this.friends=["Json","Jack"]; //方法 if(typeof this.sayName !="function"){ Person.prototype.sayName=function() { alert(this.name); }; Person.prototype.sayFriends=function() { alert(this.friends); }; } } var person = new Person("Joe",25); person.sayName(); person.sayFriends();
另外还有两个创建对象的方法,寄生构造函数模式和稳妥构造函数模式。由于这两个函数用得比较少。
12、利用Object.create()、call()组合继承创建对象
利用Object.create()、
call()继承父类得实例属性方法和原型属性方法。
Object.create()兼容IE9及以上。
function inherit(superType,subType){ var _prototype=Object.creat(superType.prototype);//获取父类prototype对象副本 _prototype.constructor=subType;//修改构造器为子类本身 subType.prototype=_prototype;//修改子类prototype对象 } function Parent(){ this.age=25; } Parent.prototype.sayName=function(){ alert(this.name); } function Child(name){ this.name=name; Parent.call(this);//获取父类得实例变量 } inherit(Parent,Child); Child.prototype.sayAge=function(){ alert(this.age);//如果需要在Child的原型上添加方法,一定要在inherit(Parent,Child)之后,否则会被覆盖 } var child=new Child(); console.log(child.age); child.sayName();
13、利用深拷贝继承创建对象
var Web={ target:"浏览者访", jiaocheng:["css教程","div教程","js教程"] } var Antzone={ webName:"蚂蚁部落", }; function deepCopy(f, c) { for (var prop in f) { if (typeof f[prop] === 'object') { c[prop] = (f[prop].constructor === Array) ? [] : {}; deepCopy(f[prop], c[prop]); } else { c[prop] = f[prop]; } } return c; } var obj=deepCopy(Web,Antzone); console.log(obj.target); console.log(obj.webName); obj.jiaocheng.push("jquery教程"); console.log(Web.jiaocheng); console.log(obj.jiaocheng);
相关文章推荐
- JavaScript总结一下--创建对象
- JavaScript学习--Item25 创建对象(类)的8种方法总结
- javascript 创建对象与继承总结和回顾
- JavaScript创建对象的几种方式总结
- JavaScript对象创建与继承总结
- Javascript 创建对象方法的总结
- Javascript 创建对象方法的总结
- JavaScript对象创建的几种方式总结
- javascript中创建对象的几种方法总结
- javascript中创建对象的几种方法总结
- JavaScript中创建类/对象的几种方法总结
- JavaScript关于创建对象和继承的一些总结
- Javascript 创建对象方法的总结
- javascript中创建对象的几种方法总结
- JavaScript对象的创建总结
- 你不知道的JavaScript--Item25 创建对象(类)的8种方法总结
- 在JavaScript中创建对象以及prototype的总结
- javascript开发:javascript面向对象、创建对象总结
- javascript开发:javascript创建对象的几种方式总结
- 你不知道的JavaScript--Item25 创建对象(类)的8种方法总结