首先,我们给出一段代码:
1 2 3 4 5 6 7 8 9 10 |
function animal(name) { this.say = function() { alert("my name is " + name); } this.init = function() { alert(name + " is created"); return this; } return this.init(); } |
下面有几中使用方式:
1. 直接执行函数,利用函数的返回值
1 2 3 4 5 6 |
var m = animal("m"); m.say(); // 结果: my name is m // 但是,因为animal("m")是在window下执行的,m只是一个返回的对象,说白了, 这里的m就是window, 没有达到封装的目的,所以,不应该让这个函数在window下执行 window.say; // 结果: my name is m |
2. 使用new来创建对象
1 2 |
var n = new animal('n'); // 此时,函数被执行,函数中的this不是window是animal n.say(); // 结果: my name is n |
3. 使用apply来创建对象
1 2 3 |
var x = {}; animal.apply(x,["x"]); //此时的animal被执行,内部的this指的是x,参数以数组的方式传递 x.say(); // 结果: my name is x |
4. 使用call来创建对象
1 2 3 |
var y = {}; animal.call(y,"y"); //此时的animal被执行,内部的this指的是y,参数以数组的方式传递 y.say(); // 结果: my name is y |
使用call和apply的区别在于传递参数的方式不同
结论:
1. 这里面只有第一种使用方法是不可取的(或者说的错误的)
2. 第二种方式容易被覆盖,所以也很少有使用,除非就不期望出现多个相同功能的对象
3. 第三、四种方式都比较容易扩展方法,被广泛使用
4. 这里的 init方法需要根据需要来决定是否公开