javaScript对象 原型继承 构造函数继承 组合继承
javaScript是脚本语言。脚本程序在执行时,是由系统的一个解释器,将其一条条的翻译成机器可识别的指令,并按程序顺序执行。脚本语言是为了缩短传统的编写-编译-链接-运行(edit-compile-link-run)过程而创建的计算机编程语言。一个脚本通常是解释执行而非编译。
数据类型
字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined)。
数组
var ar = new Array(); ar[0] = "bmw"; ar[1] = "byd"; var ar2 = ["a","b"]; var ar3 = new Array("aa","bb");
Undefined
Undefined这个值表示变量不含有值。
对象创建的几种方式
1、 var obj = new Object();
obj.name=”lmj”;
obj.age = 26;
2、 var obj = {name:”lmj”,age:26};//字面量
3、 构造函数
function Persion(name,age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var obj = new Persion(“lmj”,26);在构造函数中,给对象添加了一个sayName()方法, 所以每次在new对象的时候,都会新创建一个sayName()方法。 也就是说不同的对象拥有不同的sayName()实例。为了解决这个问题, 就需要用到原型。
4、原型模式
理解原型对象prototype
我们创建的每个函数都有一个prototype属性,这个属性是一个指针(当然可以修改这个指针)
指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。function Person(){
}
Person.prototype.name = “jack”;
Person.prototype.age = 20;
Person.prototype.sayName = function(){
alert(this.name);
}var p = new Person();
//p这个实例对象可以调用sayName方法,是由于搜索原型对象可以找到了sayName方法
p.sayName();
p.name = “zhansan”;
alert(p.name); //这个时候回输出zhansan,因为查找的时候会先从实例对象的属性中查找,查找到了name属性为zhansan,就不会再去查找prototype对象的属性,相当于prototype被屏蔽了,这个时候想要使用prototype中的属性,只有调用delete p.name方法删除实例对象的属性再来理解prototype指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
所有构造方法的实例,都有共同的prototype对象,通过查找,每个实例都用了相同的prototype所有的属性。
修改Persion.prototype指针,修改之前的实例的prototype还是指向原来的prototype,修改之后创建的实例的prototype指向修改后的指针。如果是系统默认给创建的prototype的constructor才指向Person函数
看一个prototype修改后的图片,这个把字面量对象加了constructor属性,并且指向Person。默认是指向Object
>注意问题:
>在原型对象中,添加公共的属性和方法;
>由于一个函数的原型对象只有一个,如果原型对象的属性是引用数据类型,
>那么new 出来的所有对象的引用数据类型的属性都是同一个。
>下面的例子中,第一个对象将会影响第二个对象
//输出快捷键,输出的内容.log 然后按tag键
//1、字面量创建对象
var p1 = {name:”Json”,age:26,sayName:function () {
console.log(this.name);
}};
p1.sayName();
//2、new Object
var p2 = new Object();
p2.name=”老罗”;
p2.age=36;
p2.sayName = function () {
console.log(this.name);
}
p2.sayName();
//3、构造函数
function Persion (name,age) {
this.name = name;
this.age = age;
this.sayName =function () {
console.log(this.name);
}
}
var p3 = new Persion(“罗永浩”,36);
p3.sayName();
//4、工厂方法
function PersionFactory(name,age) {
var p = new Object();
p.name = name;
p.age = age;
p.sayName = function () {
console.log(this.name);
}
return p;
}
var p4 = PersionFactory(“雷军”,46);
p4.sayName();
//5、原型模式,原型对象与funciton对应且唯一存在,这样可以解决对象funciton不被重复创建,
// 但是原型对象中的引用类型属性会被所有对象共同持有
function Phone() {
}
Phone.prototype.name=”默认手机”;
Phone.prototype.colors =[“黑”,”白”];//默认颜色
Phone.prototype.showColors = function () {
console.log(this.name+”:”+this.colors);
}
var p5 = new Phone();
p5.name = “小米”;
p5.colors.push(“灰色”);//小米添加灰色
p5.showColors();
var p51 = new Phone();
p51.name=”锤子”;
p51.showColors();
//————————————————————————————————-
/**
* 继承
* 1、直接通过原型继承,属性和方法都写在构造函数中
* 2、直接通过原型继承,属性和方法都写在原型中
* 3、直接通过构造函数继承
* 4、通过构造函数和原型组合继承
*
*/
//第一种方式
function SuperType() {
this.colors = [“black”,”white”];
this.showColors = function () {
console.log(this.colors);
}
}
function ChildType() {
}
ChildType.prototype = new SuperType();
var child1 =new ChildType();
child1.showColors();
child1.colors.push(“gary”)
var child2 = new ChildType();
child2.showColors();
/*输出结果: [ ‘black’, ‘white’ ]
[ ‘black’, ‘white’, ‘gary’ ]
明显通过原型继承,对象的属性都是来自原型,而原型唯一存在,所以引用类型变量的地址被拷贝给每一个new出来的对象
*/
// 方式2和方式1 是一样的,方式2解决了对象的方法不会被重复创建,但是原型继承还是会造成引用类型的共用
//方式3 构造函数继承
function ChildType3() {
SuperType.call(this);
}
var child31=new ChildType3();
child31.showColors();
child31.colors.push(“gary”)
var child32 = new ChildType3();
child32.showColors();
/**
* 输出结果: [ ‘black’, ‘white’ ]
[ ‘black’, ‘white’ ]
引用类型的变量并没有相互影响,其实就是相当于在子类的构造函数中,调用了父类的构造函数跑了一遍,这样父类构造函数中
声明的变量,子类也去声明了一遍,代码就复用了一下。
但是,在构造函数中声明方法属性,每个new出来的对象还是会每次都创建一个方法,所以要想方法的复用就需要组合继承
*/
//4、构造函数和原型组合继承
// 在子类中调用父类构造函数,将非方法的成员变量在构造函数中声明,将方法放在原型中声明
function SuperType4(name) {
this.name = name;
this.colors=[“blue”,”green”];
}
SuperType4.prototype.showColors = function () {
console.log(this.name+”:”+this.colors);
}
function ChildType4(name) {
SuperType4.call(this,name);//构造函数继承
}
ChildType4.prototype = new SuperType4();
var child41=new ChildType4(“Json”);
child41.colors.push(“gary”);
child41.showColors();
var child42 = new ChildType4(“Perter”);
child42.showColors();
/*
输出结果:
Json:blue,green,gary
Perter:blue,green
看出对象的引用类型没有相互影响,
所以组合继承,实现了引用类型属性独立存在,并且方法实现共用。
*/