本文共 2361 字,大约阅读时间需要 7 分钟。
function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function () { alert(this.name); } return o; } var p1 = createPerson('zed', 18, 'Doctor'); var p2 = createPerson('ls', 19, 'Engineer'); p1.sayName() p2.sayName() console.log(p1) console.log(p2)
这个模式虽然能够很方便的创建多个相似的对象,但却有个很大的问题,即对象无法识别类型,这就引出了构造函数模式。
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { alert(this.name); } } var p1 = new Person('zed', 18, 'Doctor'); var p2 = new Person('ls', 19, 'Engineer'); p1.sayName() p2.sayName() console.log(p1) console.log(p2)
以此模式创建对象,必须使用new操作符。p1和p2中分别保存着Person的两个实例对象。这两个对象都有一个属性constructor
,指向Person。
console.log(p1.constructor)//ƒ Person(name, age, job) {...} console.log(p1.constructor === p2.constructor)//true
此模式创建的对象类型,是可识别的。
console.log(typeof p1)//object console.log(p1 instanceof Person)//true console.log(p2 instanceof Person)//true
此模式大大补足了工厂模式的弊端,但是也不是完美的。
console.log(p1.sayName===p2.sayName)//false
以此模式创建的对象,所有对象中的公共方法并不是真正意义上的共享。别忘了函数也是对象,构造函数会为每个对象分别创建一个同名函数,即使他们的作用完全相同。
这么做的话,每个函数都要在每个实例对象上重新创建一遍,会浪费很多内存空间。这可不是我们想要的。这也就引出了接下来的原型模式。
function Person() { } Person.prototype.name = 'zed'; Person.prototype.age = 18; Person.prototype.job = 'Doctor'; Person.prototype.sayName = function () { alert(this.name); } var p1 = new Person(); var p2 = new Person(); console.log(p1) console.log(p2)
如果把属性和函数,挂载到对象的原型对象上,那么就可实现真正意义的共享。
console.log(p1.sayName===p2.sayName)//true
prototype
属性,这个属性会指向一个对象,这个对象包含着特定类型的所有实例对象共享的属性和方法。这个对象就叫做原型对象。constructor
属性,这个属性指向prototyoe
所在的函数。__proto__
属性,它指向原型对象。__proto__
指向的原型对象,有则返回。 function Person() { } Person.prototype = { constructor: Person, name: 'zed', age: 18, job: 'Doctor', sayName: function () { alert(this.name); } }; var p1 = new Person(); var p2 = new Person(); console.log(p1) console.log(p2)
转载地址:http://thozi.baihongyu.com/