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 0; } var person1 = createPerson('Nicholas', 29, 'software engineer'); var person2 = createPerson('greg', 27, 'doctor')
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { alert(this.name); } return 0; } var person1 = new Person('Nicholas', 29, 'software engineer'); var person2 = new Person('greg', 27, 'doctor'); alert(person1.constructor == Person) // true
构造函数始终都应该以一个大写之母开头,而非构造函数则应该以小写之母开头。javascript
建立Person的新实例,必须使用new操做符。java
构造函数与普通函数的区别app
构造函数的缺点函数
从逻辑上讲,能够这样this
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = new Function('alert(this.name)'); //与声明函数在逻辑上是等价的 } alert(person1.sayName == person2.sayName) // false
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName() { alert(this.name); } var person1 = new Person('Nicholas', 29, 'software engineer'); var person2 = new Person('greg', 27, 'doctor') // 咱们把sayName()定义在外部,person1 和person2 共享了在全局做用域中定义的同一个sayname()函数。 // 若是对象须要定义不少方法,那么就要定义不少个全局函数,因而这个自定义的引用类型没有分装性可言 // 可使用原型模式
使用原型对象的好处是可让全部对象实例共享它所包含的属性和方法prototype
function Person() { } Person.prototype.name = 'nicholas'; Person.prototype.age = 29; Person.prototype.job = 'software engineer'; Person.prototype.sayName = function () { alert(this.name); } var person1 = new Person(); person1.sayName(); // nicholas var person2 = new Person(); person2.sayName(); // nicholas alert(person1.sayName == person2.sayName); // true // 什么是原型对象 // 只要建立了一个函数,就会根据一组特定的规则为该函数建立一个prototype属性,这个属性指向函数的原型对象。 // 在默认状况下,全部的原型对象都会自动得到一个constructor(构造函数)属性。这个属性包含一个指向prototype属性所在函数的指针。 // Person.prototype constructor指向Person. // 而经过这个构造函数,咱们能够原型对象添加其余属相和方法。
function Person() { } Person.prototype = { name: 'nicholas', age: 29, job: 'software engineer', sayName: function() { alert(this.name); } } var friend = new Person();
原型链是做为实现继承的主要方法。指针
- 其基本思想就是利用原型让一个引用类型继承另外一个引用类型的属性和方法、
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; }; function SubType() { this.subproperty =false; } // 继承了supertype SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function() { return this.subproperty; } var instance = new SubType(); alert(instance.getSuperValue()) //true
使用apply() 和call() 方法也能够在未来新建立的对象上执行构造函数code
function SuperType() { this.colors = ['red', 'blue', 'green']; } function SubType() { // 继承了 supertype SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push('black'); alert(instance1.colors)// red blue green black var instance2 = new SubType(); alert(instance2.colors); // 'red', 'blue', 'green'
// 1.传递参数 function SuperType(name) { this.name = name; } function SubType() { // 继承了SuperType同时还传递了参数 SuperType.call(this, 'nicholas'); // 实例属性 this.age = 29; } var instance = new SubType(); alert(instance.name); alert(instance.age);
经过借用构造函数来实现对实例属性的继承。这样,即经过在原型上定义方法实现了函数复用,有能保证每一个实例都有它本身的属性、对象
function SuperType(name) { this.name = name; this.colors = ['red', 'blue', 'green']; } SuperType.prototype.sayName = function() { alert(this.name); } function SubType(name, age) { // 继承属性 SuperType.call(this, name); this.age = age; } // 继承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function() { alert(this.age); } var instance1 = new SubType('nicholas', 29); instance1.colors.push('black'); alert(instance1.colors);//red,blue,green,black instance1.sayName()//nicholas instance1.sayAge()// 29 var instance2 = new SubType('greg', 27); alert(instance2.colors);//red,blue,green instance2.sayName()//greg instance2.sayAge()// 27