在构造函数中 return 的意义发生了变化,首先如果在构造函数中,如果返回的是一个对象,那么就保留原意。如果返回的是非对象,比如数字、布尔和字符串,那么就返回 this,如果没有 return 语句,那么也返回 this,看下面代码:
复制代码 代码如下:
// 返回一个对象的 return
var ctr = function() {
this.name = "赵晓虎";
return {
name:"牛亮亮"
};
};
// 创建对象
var p = new ctr();
// 访问name属性
alert(p.name);
执行代码,这里打印的结果是”牛亮亮”。因为构造方法中返回的是一个对象,那么保留 return 的意义,返回内容为 return 后面的对象,再看下面代码:
复制代码 代码如下:
// 定义返回非对象数据的构造器
var ctr = function() {
this.name = "赵晓虎";
return "牛亮亮";
};
// 创建对象
var p = new ctr();
// 使用
alert(p);
alert(p.name);
代码运行结果是,先弹窗打印[object Object],然后打印”赵晓虎”,因为这里 return 的是一个字符串,属于基本类型,那么这里的 return 语句无效,返回的是 this 对象,因此第一个打印的是[object Object]而第二个不会打印 undefined。
四、apply调用模式
除了上述三种调用模式以外,函数作为对象还有 apply 方法与 call 方法可以使用,这便是第四种调用模式,我称其为 apply 模式。
首先介绍 apply 模式,首先这里 apply 模式既可以像函数一样使用,也可以像方法一样使用,可以说是一个灵活的使用方法。首先看看语法:函数名.apply(对象, 参数数组);
这里看语法比较晦涩,还是使用案例来说明:
1、新建两个 js 文件,分别为”js1.js”与”js2.js”;
2、添加代码
复制代码 代码如下:
// js1.js 文件中
var func1 = function() {
this.name = "程序员";
};
func1.apply(null);
alert(name);
// js2.js 文件
var func2 = function() {
this.name = "程序员";
};
var o = {};
func2.apply(o);
alert(o.name);
3、分别运行着两段代码,可以发现第一个文件中的 name 属性已经加载到全局对象 window 中; 而第二个文件中的 name 属性是在传入的对象 o 中,即第一个相当于函数调用,第二个相当 于方法调用。
这里的参数是方法本身所带的参数,但是需要用数组的形式存储在,比如代码:
复制代码 代码如下:
// 一个数组的例子
var arr1 = [1,2,3,[4,5],[6,7,8]];
// 将其展开
var arr2 = arr1.conact.apply([], arr1);
然后介绍一下 call 模式,call 模式与 apply 模式最大的不同在于 call 中的参数不用数组,看下面代码就清楚了:
// 定义方法
var func = function(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
};
// 创建对象
var o = {};
// 给对象添加成员
// apply 模式
var p1 = func.apply(o, ["赵晓虎", 19, "男"]);
// call 模式
var p2 = func.call(o, "赵晓虎", 19, "男");
上面的代码,apply 模式与 call 模式的结果是一样的。
实际上,使用 apply 模式和 call 模式,可以任意的操作控制 this 的意义,在函数 js 的设 计模式中使用广泛。简单小结一下,js 中的函数调用有四种模式,分别是:函数式、方法式、构造 器式和 apply 式. 而这些模式中,this 的含义分别为:在函数中 this 是全局对象 window,在方 法中 this 指当前对象,在构造函数中 this 是被创建的对象,在 apply 模式中 this 可以随意的指定.。在 apply 模式中如果使用 null,就是函数模式,如果使用对象,就是方法模式。
五、综合例子
下面通过一个案例结束本篇吧。案例说明:有一个div,id为dv,鼠标移到上面去高度增大2倍,鼠标离开恢复,下面直接上js代码:
复制代码 代码如下: