JavaScript_几种创建对象(2017-07-04)
理解对象
1.创建Object实例
var clock = new Object(); clock.hour = 12; clock.minute = 10; clock.showHour = function() { alert(clock.hour); }; clock.showHour(); //调用
属性是可以动态添加,修改的
2.对象字面量
var clock = { hour: 12, minute: 10, second: 10, showTime: function() { alert(this.hour + ":" + this.minute + ":" + this.second); } } clock.showTime(); //调用
对象字面量方式创建对象是首选
创建对象
1.工厂模式:(不推荐使用这种方式创建对象,但应该了解)
//就是一个函数,然后放入参数,返回对象,流水线工作 function createClock(hour, minute, second) { var clock = new Object(); clock.hour = hour; clock.minute = minute; clock.second = second; clock.showHour = function() { alert(this.hour + ":" + this.minute + ":" + this.second); }; return clock; }; var newClock = createClock(12, 12, 12); //实例化 newClock.showHour(); //调用
说明:
不能识别对象的类型(instanceof 根据实例对象的内部属性__proto__与函数的原型对象是否相等来判断实例是否属于该对象类型的)
2.构造函数模式(不推荐使用这种方式创建对象,但仍需要了解)
function clock(hour, minute, second) { this.hour = hour; this.minute = minute; this.second = second; this.showTime = function() { alert(this.hour + ":" + this.minute + ":" + this.second); } } var newClock = new clock(12, 12, 12); alert(newClock.hour);
注意:这个new关键字是必须,如果不加,clock就不会当成构造函数调用,而只是一个普通的函数。同时,还会意外地给他的外部作用域即window添加属性,因为此时构造函数内部的this已经映射到了外部作用域了。所以为了安全起见,可以这样创建
function clock(hour, minute, second) { if (this instanceof clock) {//new的实例是否为clock类型,如果不用this代表作用域可能是全局global变量。 this.hour = hour; this.minute = minute; this.second = second; this.showTime = function() { alert(this.hour + ":" + this.minute + ":" + this.second); } } else { throw new Error("please add 'new' to make a instance"); } }
说明:
与工厂方式相比,使用构造函数方式创建对象,无需再函数内部重建创建对象,而使用this指代,并而函数无需明确return。
由于this指针在对象实例的时候发生改变指向新的实例。这时新实例的方法也要重新创建,如果n个实例就要n次重建相同的方法。
3.原型模式(不推荐使用这种方式创建对象,但仍需要了解)
function clock(hour, minute, second) { } clock.prototype.hour = 12; clock.prototype.minute = 12; clock.prototype.second = 12; clock.prototype.showTime = function() { alert(this.hour + ":" + this.minute + ":" + this.second); } var newClock = new clock(); newClock.showTime();
当然可以这样写:
function clock(hour, minute, second) {
} clock.prototype = { constructor: clock,//必须手动设置这个属性,不然就断了与构造函数的联系了。没有实例共享原型的意义了。 hour: 12, minute: 12, second: 12, showTime: function() { alert(this.hour + ":" + this.minute + ":" + this.second) } } var newClock = new clock(); newClock.showTime();
理解调用过程可以参考:JavaScript_原型和继承(2017-03-15)
JS中万物皆对象,但分为两大类:普通对象和函数对象。所有的函数对象都有一个prototype属性,普通对象是没有prototype属性的,只有_proto_
说明:
原型模式虽然解决了构造函数每个方法都会在每个实例中重新创建一遍的问题。但是所有实例在默认情况下都取得了相同的属性值,实例一般都是要有属于自己的全部属性的。
4.组合使用构造函数模式和原型模式(混合模式,推荐)
function clock(hour, minute, second) { this.hour = hour; this.minute = minute; this.second = second; } clock.prototype.showTime = function() { alert(this.hour + ":" + this.minute + ":" + this.second); } var newClock = new clock(12, 12, 12); newClock.showTime();
该模式是指混合搭配使用构造函数方式和原型方式
说明:
将所有属性不是方法的属性定义在函数中(构造函数方式,私有private)
将所有属性值为方法的属性利用prototype在函数之外定义(原型方式,共享public)
5.动态原型方式
function Parent() { this.name = "李小龙"; this.age = 32;; //方式1 通过函数对象有无此属性来决定 if (typeof Parent._lev == "undefined") {// 这段代码只执行了一次 Parent.prototype.lev = function() { return this.name; } Parent._lev = true; } //方式2 通过实例对象根据原型链寻找有无此属性来决定 if (typeof this.lev != 'function') {// 这段代码只执行了一次 Parent.prototype.lev = function() { return this.name; } } }; var x = new Parent(); alert(x.lev());
动态原型方式可以理解为混合构造函数,原型方式的一个特例
说明:
该模式中,属性为方法的属性直接在函数中进行了定义,但是因为方式1,2的判定。从而保证创建该对象的实例时,属性的方法不会被重复创建
6 寄生构造函数模式(没理解,不先写)
7 稳妥构造函数模式(没理解,不先写)
copy: