对象的建立有两种方式,一种是直接用大括号直接建立,还有一种是用Object.create方法。函数
“var person1 = { name: "Nicholas", sayName: function() { console.log(this.name); } };”
var person2 = Object.create(person1, { name: { configurable: true, enumerable: true, value: "Greg", writable: true } });
实际应用过程当中,第二种方式比较少见。this
####1.Function方式 若是有以下函数,建立对象的实例一般用以下方式:prototype
function Person(name) { this.name = name; this.sayName = function() { console.log(this.name); }; } var p = new Person("aaa");
构造函数在哪里?是什么样子的?其实这个时候,JS引擎隐式的构建了以一个构造函数,Person.prototype.constructor, 在new这个对象的时候,调用了这个构造函数,p.constructor == Person.prototype.constructor。 ####2. Prototype方式 用第一种方式存在一个问题,即每一个对象都会拥有name和sayName两个属性。而sayName做为操做数据的方法,其实没有必要每一个对象都有一份拷贝。为了节省内存和更好的区分对象的数据和方法,一般会把方法放到prototype里。形式以下:code
function Person(name) { this.name = name; } Person.prototype.sayName = function(){ console.log(this.name); }
这两种方式生成的对象的行为和方法是同样的,可是第二种方式的sayName不在是对象实例的OwnProperty,检测结果将返回false:对象
var p1 = new Person("a") p1.hasOwnProperty('sayName') //false
那么既然第二种方式更好,在定义多个方法的时候,有人会进一步简化成:内存
function Person(name) { this.name = name; } Person.prototype= { sayName:function(){ console.log(this.name); }, sayHi:function(){ console.log('Hi'+this.name); } }
这样看似很好,可是检测下构造函数后,发现有问题:it
Person.prototype.constructor //function Object() { [native code] }
这是由于Person.prototype={}的过程当中,Object的constructor覆盖了Person.prototype.constructor。解决方法是把constructor从新覆盖回来。io
Person.prototype= { constructor:Person, sayName:function(){ console.log(this.name); }, sayHi:function(){ console.log('Hi'+this.name); } }