在其他语言中,new操作符都是用来实例化创建一个对象的,JavaScript 中同样如此,但是它又有一些不同。为了说清楚这个问题我们先来看一下JavaScript 中的类、原型、原型链、继承这些概念吧。
function Person(name, age) { this.name = name; this.age = age; this.sing = function() { alert(this.name) } }
function Foo() { this.value = 42; } Foo.prototype = { method: function() {} }; function Bar() {} // 设置Bar的prototype属性为Foo的实例对象 Bar.prototype = new Foo(); Bar.prototype.foo = ‘Hello World‘; // 修正Bar.prototype.constructor为Bar本身 Bar.prototype.constructor = Bar; var bar= new Bar() // 创建Bar的一个新实例 // 原型链 test [Bar的实例] Bar.prototype [Foo的实例] { foo: ‘Hello World‘ } Foo.prototype {method: ...}; Object.prototype {toString: ... /* etc. */};
上面的例子中,test 对象从 Bar.prototype 和 Foo.prototype 继承下来;因此, 它能访问 Foo 的原型方法 method。同时,它也能够访问那个定义在原型上的 Foo 实例属性 value。 需要注意的是 new Bar() 不会创造出一个新的 Foo 实例,而是 重复使用它原型上的那个实例;因此,所有的 Bar 实例都会共享相同的 value 属性。
var foo = {}; foo.__proto__ = Object.prototype; Object.call(foo);
同理,当我们new Bar()的时候,也是创建了一个空对象,并且 this 变量引用该对象,同时,Bar.prototype = new Foo();然后bar.__proto__ = Foo.prototype,最后,由Foo.call(bar)隐式的返回了this; 其中,Bar.prototype = new Foo()会使得Bar.prototype.constructor == Foo,所以这里我们要使用Bar.prototype.constructor = Bar;把Bar自身的构造函数修正过来。
function A() {} A.prototype.x = 10; var a = new A(); alert(a.x); // 10 – 从原型上得到 // 设置.prototype属性为新对象 // 为什么显式声明.constructor属性将在下面说明 A.prototype = { constructor: A, y: 100 }; var b = new A(); // 对象"b"有了新属性 alert(b.x); // undefined alert(b.y); // 100 – 从原型上得到 // 但a对象的原型依然可以得到原来的结果 alert(a.x); // 10 - 从原型上得到 function B() { this.x = 10; return new Array(); } // 如果"B"构造函数没有返回(或返回this) // 那么this对象就可以使用,但是下面的情况返回的是array var b = new B(); alert(b.x); // undefined alert(Object.prototype.toString.call(b)); // [object Array]
这里有两个主要特点:
说说JavaScript 中的new吧,布布扣,bubuko.com
原文:http://www.cnblogs.com/jackyWHJ/p/3756745.html