function A(){ console.log(this); this.v = 1; } A(); // this = window new A(); // this instanceof A
function A(){ console.log(this); this.v = 1; return {c:3}; } var a = new A(); // a = {c:3} a instanceof A; // false
var inst = {}; inst__proto__ = A.prototype; A.call(inst); // 把A当作普通函数调用
用new
创建对象需要指定参数序列。如果参数需要动态传入,则可以借助bind
方法。
function A() {this.v=3;} function makeA(){ var f = A.bind.apply(null, arguments); return new f(); }
另一种方法是利用
function makeA(){ var inst = {}; inst.__proto__ = A.prototype; A.apply(inst, arguments); return inst; }
上面的实现也可以借助var inst = Object.create(A.prototype)
来实现。
构造函数是为了创建对象,创建对象是为了使用其成员变量或者成员函数。
function A1(){ this.v = 0; this.func = function(v){this.v=v;} } function A2(){} A2.prototype.func = function(v){this.v=v;} A3 = { v: 0, func: function(v){this.v=v;} } var a1 = new A1() var a2 = new A(); var a3 = A3;
从创建对象的角度来讲,效率排序为:A3 > A2 > A1。
从访问成员的角度来讲,效率排序为:A3 > A1 > A2。
A3 可以认为是 Singleton 模式的实现。
需要频繁创建对象的情况下,可以通过A2的实现模式提高效率和减少内存。
A2所引起的成员访问负担在prototype链不是很长的情况下应该也不是大问题。
function A(){ this.v = 1; } var a = new A(); a.__proto__ == A.prototype; // true console.log(A.prototype); // {constructor: function A() {this.v=1;}, // __proto__: Object} console.log(A.constructor); // function Function() {[native code]} console.log(a.constructor); // function A() {this.v=1;}
function A(){ this.v = 1; } var a = new A(); a instanceof A ; // true: A.prototype is in __proto__ chain a.__proto__ == A.prototype; // true
arguments
的使用看起来像是Array,其实不是。
Array.prototype.slice.call(arguments, 0); // to array