1.对象
1.1有两种方式创建对象
var p1 = new Object();
p1.name="张三";
p1.age=18;
p1.gender="男";
p1.show=function(){
console.log(this.name);
}
var p2 = {
name="李四",
age=19,
gender="女"
show=function(){
console.log(this.name)
}
};
1.2访问数据也有两种方式
//点表示法
console.log(p1.name)
//括号表示法
console.log(p1["name"])
1.3子命名空间
可以用一个对象来做另一个对象成员的值。例如将name成员
name:["王五","赵六"]
//改为
name:{
name1:"王五",
name2:"赵六"
}
1.4简单工厂模式
function creat(name,age,gender){
var p = new Object();
p.name = name;
p.age = age;
p.gender = gender;
p.showInfo=function(){
console.log("我叫"+this.name+",我今年"+this.age+"岁了")
}
return p;
}
//创建
var p = creat("小美",18,"女");
console.log(p);
p.showInfo();
var p2 = creat("小帅",19,"男");
console.log(p2);
p2.showInfo();
在以上代码可以看出creat()就是一个工厂,参数接收构建Person对象所必要的信息。可以无数次调用creat()函数,每调用一次,他就会返回一个对象。简单工厂模式与基于Object单个对象创建的方式对比,在批量创建对象时避免了大量的重复代码。
2.构造函数和原型对象
2.1构造函数
构造函数可用来创建特定类型的对象。像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中。
//构造函数通常首字母大写
function Student(name,age,email,hobby){
this.name=name;
this.age=age;
this.email=email;
this.hobby=hobby;
this.showName=function(){
alert(this.name);
}
}
var stu1=new Student("张三",18,"zhangsan@163.com","打球");
stu1.showName();
var stu2=new Student("李四",19,"lisi@163.com","看书");
stu2.showName();
在上面代码中,stu1和stu2分别保存着Student的一个不同的实例。这两个对象都有一个constructor(构造函数)属性,这个属性指向Student。
console.log(stu1.constructor==Student);//输出:true
console.log(stu2.constructor==Student);//输出:true
对象中constructor属性最初是用来标记类型的,在开发过程中,有时还需要检测对象类型, 如typeof运算符。instanceof运算符与typeof运算符相似,都是用于识别正在处理的对象的类型。与typeof运算符不同的是,instanceof运算符要求开发者明确地确认对象为某特定类型。
console.log(stu1 instanceof Object);//true
console.log(stu1 instanceof Student);//true
2.2 原型对象
js中所有创建的每个函数都有一个prototype(原型)属性,这个属性指向一个对象,即原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。
语法:构造函数名.prototype.新属性或新方法
3.继承
3.1原型链
ES中将原型链作为实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。在js中,每个构造函数都拥有一个原型对象,原型对象包含一个指向构造函数的内部属性(constructor),实例都包含一个指向原型对象的内部属性(__proto__)。假如一个原型对象等于另一个类型的实例,另一个类型的原型对象又等于另一个类型的实例,如此层层递进,就构成了实例与原型的链条,这就是所谓的原型链。
子对象.prototype=new 父对象()
3.2 对象继承
原型链虽然可以实现继承,但是也存在以下两个问题:
1.包含引用类型值的原型,由于包含引用类型值的原型属性会被所有实例共享,在通过原型实现继承时,原型实际上会变成另一个类型的实例,所以原先的实例属性也就变成了现在的原型属性了。
2.在创建子类型的实例时,不能向父类型的构造函数中传递参数。
基于这两个问题,一般在实际开发中很少会单独使用原型链。因此会使用伪造对象或经典继承。
3.2.1 借用构造函数
借用构造函数的基本思想很简单,即在子类型构造函数的内部调用父类型的构造函数。可以通过apply()方法或call()方法进行调用,
语法:apply(this,[argArray]); call(this,arg1,arg2,argN);
3.2.2 组合继承
组合继承也被称为伪经典继承,指的是将原型链和借用构造函数的技术组合到一起,从而发挥二者之长的一种继承模式。
function Per(namee,age){
this.namee=namee;
this.age=age;
this.set = ["米饭"];
}
Per.prototype.show=function(){
console.log("I'm"+this.namee);
}
function Student(namee,age,stuid,clas){
Per.apply(this,[namee,age]);
this.stuid=stuid;
this.clas=clas;
}
Student.prototype=new Per();
Student.prototype.xuexi=function(){
console.log("I'm"+this.clas);
}
var stu1=new Student("张三",19,1001,"01班");
stu1.show();
console.log(stu1);
stu1.xuexi();
stu1.set.push("苹果");
console.log(stu1.set);
var stu2=new Student("李四",19,1002,"02班");
stu2.set.push("apple");
console.log(stu2.set);
本章总结
挑战极限,无悔人生奋力拼搏进取,谱写风华篇章。