- js函数中使用this来构造对象
function Person(name) //带参数的构造函数
{
this.name = name; //将参数值赋给给 this 对象的属性
this.SayHello = function() {alert("Hello, I'm " + this.name);}; //给this对象定义一个SayHello方法。
};
function Employee(name, salary) //子构造函数
{
Person.call(this, name); //将 this传给父构造函数
this.salary = salary; //设置一个 this 的 salary属性
this.ShowMeTheMoney = function() {alert(this.name+" $" + this.salary);}; //添加ShowMeTheMoney方法。
};
var BillGates = new Person("Bill Gates"); //用 Person 构造函数创建 BillGates 对象
var SteveJobs = new Employee("Steve Jobs", 1234); //用 Empolyee构造函数创建 SteveJobs对象
BillGates.SayHello(); //显示:I'm Bill Gates
SteveJobs.SayHello(); //显示:I'm Steve Jobs
SteveJobs.ShowMeTheMoney(); //显示:Steve Jobs $1234
alert(BillGates.constructor == Person); //显示:true
alert(SteveJobs.constructor == Employee); //显示:true
alert(BillGates.SayHello == SteveJobs.SayHello); //显示:false
- 使用 Person.prototype 来创建原型,结果发现 Employee 对象没有SayHello()方法: 这就是this和prototype的区别。
当你 反注释掉Person()函数里的 //this.SayHello = function() {alert("Hello, I'm " + this.name);}; 会发现 Employee 对象 总算有 SayHello()方法了!
或者反注释掉 // Employee.prototype = new Person(); 那么 Employee 对象 SteveJobs调用 SteveJobs.SayHello()时会使用prototype链最终找到SayHello()方法。
function Person(name) //基类构造函数
{
this.name = name;
//this.SayHello = function() {alert("Hello, I'm " + this.name);};
};
Person.prototype.SayHello = function() //给基类构造函数的prototype添加方法
{
alert("Hello, I'm " + this.name);
};
function Employee(name, salary) //子类构造函数
{
Person.call(this, name); //调用基类构造函数
this.salary = salary;
};
// Employee.prototype = new Person(); //建一个基类的对象作为子类原型的原型,这里很有意思
Employee.prototype.ShowMeTheMoney = function() //给子类添构造函数的 prototype添加方法
{
alert(this.name + " $" + this.salary);
};
var BillGates = new Person("Bill Gates"); //创建基类 Person 的BillGates 对象
var SteveJobs = new Employee("Steve Jobs", 1234); //创建子类 Employee的 SteveJobs对象
BillGates.SayHello(); //通过对象直接调用到prototype的方法
SteveJobs.SayHello(); //通过子类对象直接调用基类 prototype的方法,关注!
SteveJobs.ShowMeTheMoney(); //通过子类对象直接调用子类 prototype的方法
alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true,表明 prototype的方法是共享的
在JavaScript内部,对象的属性和方法追溯机制是通过所谓的prototype链来实现的。当用new操作符构造对象时,也会同时将
构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。
使用console.dir()打印bill显示其原型是Object,steve的原型则是Person函数!并不会因为Employee函数里使用了Person.call(this, name); 就真正有父子类的关系,最多只是父子构造函数——此处并不改变原型,各自原型都还是Object。所以说没有父子类的关系。
最多只是在Employee的对象的constructor中可以看到Person函数,Employee对象和Person对象的原型其实都是Object。
只有原型上的关系可以考虑为父子类。
console.dir(BillGates)
VM198:1 Personname: "Bill Gates"__proto__: ObjectSayHello: ()constructor: Person(name)__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()
console.dir(SteveJobs)
VM199:1 Employeename: "Steve Jobs"salary: 1234__proto__: PersonShowMeTheMoney: ()name: undefined__proto__: ObjectSayHello: ()constructor: Person(name)__proto__: Object
- bill和下面的aaa还是有区别的.bill是封装了一层的自定义的Object。而且其SayHello()函数是使用this定义还是使用原型定义,console.dir()看到的当然完全不同了
aaa={}
Object {}
console.dir(aaa)
VM225:1 Object__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()
console.dir(BillGates)
VM254:1 PersonSayHello: ()name: "Bill Gates"__proto__: Objectconstructor: Person(name)__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()