1.声明一个对象
var myperson={
name : "Zhang",
age : 25,
sex : "male",
introduction:function(){
alert(name+age+sex);
}
};
myperson.introduction();
2.使用构造函数构造
构造函数与普通函数的区别在于调用方式,构造函数使用new方法构造。
function creatrPerson(name,age,sex,interests){
this.name = name;
this.age = age;
this.sex = sex;
this.interests = interests;
this.bio = function(){
var res = "";
if(this.sex == "male"){
res+="He ";
}else if(this.sex=="female"){
res+="She ";
}else{
res+="It "
}
for(var i=0;i<interests.length;i++){
res+="likes "+interests[i];
if(i!=interests.length-1){
res+=" and ";
}
}
alert(res);
}
}
var zhang = new creatrPerson("zhang",18,"male",["basekatball","swiming","singing"]);
zhang.bio();
首先创建了一个空对象,之后使用点或括号表示法向此对象添加属性和方法
var person1 = new Object();
person1.name = 'Chris';
person1['age'] = 38;
person1.greeting = function() {
alert('Hi! I\'m ' + this.name + '.');
}
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象。
注意:与Java的面向对象设计不同,java中存在类的概念,创建对象后,会将类的属性和方法复制到对象中。
而JS中,会通过_proto_属性来建立构造方法与对象实例的连接。
每个 function方法中都具有 prototype 属性,其对应的也就是我们通过 function 构造出实例的 proto 属性。接下来举个例子。
function doSomething(){}
doSomething.prototype.foo = "bar"; // add a property onto the prototype
var doSomeInstancing = new doSomething();
doSomeInstancing.prop = "some value"; // add a property onto the object
console.log( doSomeInstancing );
对应输出如下,可以看到实例对象的_proto_对应构造函数的 protoype(因为设置了foo这个属性)。同时注意一点,JS会在需要某个对象的属性时,会首先去寻找该对象是否存在该属性,之后会去对象的_proto_属性中寻找,依次类推,如果找不到则会判断该属性为Undefined,这条链路被称为原型链。
doSomeInstacing对象 的 proto 属性对应的的就是 dosomething构造函数 的 prototype 属性
{
prop: "some value",
__proto__: {
foo: "bar",
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
}
我们可以进一步理解原型链。我们使用之前cteatePerson
方法去构造一个对象 Zhang。可以看到 Zhang 对象有多个属性或方法供我们使用。
原型链的访问顺序:Zhang->createPerson->Object
1.prototype 属性
继承的属性和方法都在prototype中定义。这也就是为什么上文访问 Zhang.valueOf 能返回具体的值,因为Object.prototype.valueOf 可以供任何继承自它的对象使用。
而任何不在 prototype 中的属性或方法仅能供 Object 自己使用,继承自它的对象无法使用。
2.constructor 属性
每个实例对象都从原型对象那里继承了一个构造器,下述代码都会返回 CreatePerson()构造器。
person1.constructor
person2.constructor
我们同样可以使用构造器来构造对象。
person3 = new person1.constructor("feng",20,"male",["hha","aaa"]);
3.修改原型
我们尝试修改(添加)构造器中的prototype
属性。
creatrPerson.prototype.farewell = function() {
alert(this.name + ' has left the building. Bye for now!');
}
之后调用对象实例的 farewell
方法。浏览器会通过原型链找到构造器的prototype
对象,并调用farewell
方法
zhang.farewell()
值得注意的是,我们首先创建的的对象实例,之后才为构造器添加属性(方法),对象实例仍然能通过原型链找到该方法。
证明了下游对象(Zhang)在创建时不是复制了上游对象(构造函数的prototype)的方法和属性,而是建立了联系。在访问下游对象未定义的方法时,下游对象可以通过原型链访问到上游对象中的对应方法。
可以通过上述文章了解,JS的继承和Java不同,是通过原型链来完成的。因此我们接着尝试创建继承自另一个对象的的JS对象。