最近在看javascript高级程序设计,其中对对象的创建做了具体的阐述,可以进行总结一下。
第1种模式:工厂方式 var sayHello=function(){ return "Hello"; }; function student(){ var S1 = new Object(); Child.name="小明"; Child.age="18"; Child.sayHello=sayHello; return student; }; var x = student(); alert(x.name); alert(x.sayHello());
说明:
1.在函数中定义对象,并定义对象的各种属性,,虽然属性可以为方法,但是建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法
2.引用该对象的时候,这里使用的是 var x = Parent()而不是 var x = new Parent();因为后者会可能出现很多问题(前者也成为工厂经典方式,后者称之为混合工厂方式),不推荐使用new的方式使用该对象
3.在函数的最后返回该对象
4.不推荐使用这种方式创建对象,但应该了解、
第2种模式:构造函数方式 var sayHello =function(){ return "Hello"; }; function student(){ this.name = "小明"; this.age = "18"; this.sayHello = sayHello; }; var x =new stdent(); alert(x.name); alert(x.sayHello ());
说明:
1.与工厂方式相比,使用构造函数方式创建对象,无需再函数内部重建创建对象,而使用this指代,并而函数无需明确return
2.同工厂模式一样,虽然属性的值可以为方法,仍建议将该方法定义在函数之外
3..同样的,不推荐使用这种方式创建对象,但仍需要了解
第3种模式:原型模式 var sayHello=function(){ return "hello"; }; function student(){ }; student.prototype.name="小明"; student.prototype.age="18"; student.prototype.sayhello=sayhello; var x =new student(); alert(x.name); alert(x.sayhello());
说明:
1.函数中不对属性进行定义
2.利用prototype属性对属性进行定义
3.同样的,不推荐使用这样方式创建对象
第四种模式:混合的构造函数,原型方式(推荐) function student(){ this.name="小明"; this.age=18; }; Parent.prototype.sayname=function(){ return this.name; };; var x =new student(); alert(x.sayname());
说明:1.该模式是指混合搭配使用构造函数方式和原型方式
2.将所有属性不是方法的属性定义在函数中(构造函数方式)
将所有属性值为方法的属性利用prototype在函数之外定义(原型方式)
这样做有利于所有实例共用一个函数,无需重复定义,定义在对象原型的函数能被所有实例调用。
第五种模式:动态原型方式 function student(){ this.name="小明"; this.age=18; ; if(typeof Parent.sayname=="undefined"){ //直接在函数体内定义,如果函数没有被定义则进行定义 Parent.prototype.sayname=function(){ return this.name; } Parent.sayname = true; } }; var x =new student(); alert(x.sayname());
说明:
1.动态原型方式可以理解为混合构造函数,原型方式的一个特例,只是对实例化对象前,进行了条件判断
2.该模式中,属性为方法的属性直接在函数中进行了定义,但是因为函数中存在条件判断语句,从而保证创建该对象的实例时,属性的方法不会被重复创建
3.推荐使用这种模式
二.对象的原型链
在知道几种常见的方式在JS中创建对象之后,再来了解下继承的问题。
首先应当明确:在JavaScript中,一切都是对象(包括函数)
JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象;
(1) 例如创建一个Array对象时
var arr = [1, 2, 3]; 此时原型链为:arr ----> Array.prototype ----> Object.prototype ----> null
(2) 创建一个函数
function foo() { return 0; }
它的原型链为:foo ----> Function.prototype ----> Object.prototype ----> null
当我们访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后,如果还没有找到,就只能返回undefined。
构造函数
除了直接用{..}创建一个对象外,JavaScript还可以用一种构造函数的方法来创建对象。它的用法是,先定义一个构造函数:
function Student(name) { this.name = name; this.hello = function () { alert(‘Hello, ‘ + this.name + ‘!‘); } }
这和普通函数并没有区别,但是在JavaScript中,可以用关键子[ new ]来调用这个函数,并返回一个对象:
var xiaoming = new Student(‘小明‘); xiaoming.name; // ‘小明‘ xiaoming.hello(); // Hello, 小明!
注意,如果不写new,这就是一个普通函数,它返回undefined。但是,如果写了new,它就变成了一个构造函数,它绑定的this指向新创建的对象,并默认返回this,也就是说,不需要在最后写return this;。
新创建的xiaoming的原型链是:
xiaoming ----> Student.prototype ----> Object.prototype ----> null
也就是说,xiaoming的原型指向函数Student的原型。如果你又创建了xiaohong、xiaojun,那么这些对象的原型与xiaoming是一样的:
xiaoming xiaohong -→ Student.prototype ----> Object.prototype ----> null xiaojun
用new Student()创建的对象还从原型上获得了一个constructor属性,它指向函数Student本身:
xiaoming.constructor === Student.prototype.constructor; // true Student.prototype.constructor === Student; // true Object.getPrototypeOf(xiaoming) === Student.prototype; // true xiaoming instanceof Student; // true
红色箭头是原型链。注意,Student.prototype指向的对象就是xiaoming、xiaohong的原型对象,这个原型对象自己还有个属性constructor,指向Student函数本身。
另外,函数Student恰好有个属性prototype指向它的原型,但是xiaoming、xiaohong这些对象可没有prototype这个属性,不过可以用__proto__这个非标准用法来查看。
现在我们就认为xiaoming、xiaohong这些对象“继承”自Student。
以上是我决定近期学习JS的一些比较好参考资料与自己的心得体会
希望对大家有帮助
参考资料:《Javascript高级程序设计》
廖雪峰Blog 《JS教程》