首页 > 代码库 > javascript面向对象和原型
javascript面向对象和原型
// 1.) 判断类型 typeof
// 2.) instanceof
function Box(name , age)
{
this.name=name;
this.age=age;
this.run=function()
{
return this.name + this.age+‘运行中...‘;
}
}
var box1= new Box(‘lee‘ , 100);
alert(box1.run());
alert(box1 instanceof Box) //★ instanceof 创造这个实例的构造函数是(条件是已知构造函数的名称)
// 3.)在构造函数创建的时候 会成一个指针 _proto_ 指向构造函数 prototype【原型里面】 里的constructor 【←构造属性】
// 4.) constructor
alert(box1.constructor); => Box(){} //可以获取构造函数本生
// 5.) isPrototypeOf ★判断一个对象实例(对象引 用)是不是指向了构造函数的原型对象(已知构造函数的名称),基本上,只要实例化了,他是自动指向的
function Box(){};
Box.prototype.name=‘lee‘;
Box.prototype.age=100;
Box.prototype.run=function()
{
return this.name + this.age+‘运行中...‘;
};
var box1 = new Box();
alert(Box.prototype.isPrototypeOf(box1));
// 6.) 原型模式的执行流程
优先 寻找实例里面的属性
// 7.) hasOwnProperty //判断属性是不是在构造函数实例里面
function Box()
{
this.name="KSA";
};
Box.prototype.name=‘lee‘;
Box.prototype.age=100;
Box.prototype.run=function()
{
return this.name + this.age+‘运行中...‘;
};
var box1 =new Box();
alert(box1.hasOwnProperty(‘name‘));
// 8.) in //不管实例属性 或者 原型属性 只要有就返货true两边都没有返回false
function Box()
{
this.name="KSA";
};
Box.prototype.name=‘lee‘;
Box.prototype.age=100;
Box.prototype.run=function()
{
return this.name + this.age+‘运行中...‘;
};
var box1 =new Box();
alert(‘name‘ in box1);
//★扩展。判断 只有 原型中有属性
function isProperty(object , property)
{
//如果在原型里面 返回 true
return !object.hasOwnProperty(property)&&(property in object);
}
// 9.) 字面量 创建 原型
//★ 使用字面量的方式创建原型对象,这里{}就是对象,是Object,new Object就相当于{}
function Box(){};
Box.prototype={
constructor:Box, //强制指向构造函数
name:‘lee‘,
age:100,
run:function()
{
return this.name + this.age+‘运行中...‘;
};
}
//字面量的方式重写会切断与原型的关系
Box.prototype ={
age:200 //这里不会保留原型的任何信息了
//把原来的原型对象和构造函数对象实例之前的关系切断
}
alert(Box.name) => undefined
// 10.) 查看sort是否是Array原型对象里的方法
alert(Array.prototype.sort);
alert(String.prototype.substring);
//内置引用类型的功能的扩展
String.prototype.addstring =function()
{
return this + ‘被添加了‘
}
var box = ‘Lee‘;
alert(box.addstring());
// 11.) 解决原型上独立性 和 共享的问题
function Box( name , age)
{
this.name = name;
this.age = age;
this.family = [‘哥哥‘ , ‘姐姐‘ , ‘弟弟‘]; //保持独立的用构造函数
}
Box.prototype={
constructor:Box;
run:function()
{
return this.name + this.age +this.family; //需要共享的写在原型里面
}
}
---------------------------------------------------------------------------
//动态原型模式
//可以将原型封装到构造函数里面
function Box(name , age)
{
this.name =name;
this.age=age;
this.family=[‘哥哥‘ , ‘姐姐‘ , ‘弟弟‘];
//开始
Box.prototype.run = function()
{
return this.name +this.age + ‘运行中...‘;
}
//结束
//问题是每当构造函数创建对象的时候 原型都会执行一次【换句话说 构造函数创建多少次,原型就初始化多少次】
}
---------------------↓-----解决如下
function Box(name , age)
{
this.name =name;
this.age=age;
this.family=[‘哥哥‘ , ‘姐姐‘ , ‘弟弟‘];
if( typeof this.run != ‘function‘)
{
//开始
Box.prototype.run = function()
{
return this.name +this.age + ‘运行中...‘;
}
//结束
}
}
-------------寄生构造函数 = 工厂模式+构造函数
function myString(string)
{
var str =new String(string);
str.addstring =function()
{
return this+‘被添加‘;
}
return str;
}
var box =new myString(‘Lee‘);
alert(box.addstring());
-------------稳妥构造函数
function Box( name ,age)
{
var obj =new Object();
obj.run =function()
{
return name +age +‘运行中‘;
}
return obj;
}
var box = Box(‘Lee‘,100); //直接调用函数
alert(box.run());
// 12.) 继承★
//1> 继承,通过原型链实现
function Box() //被继承的函数叫做超类型(父类 ,基类)
{
this.name = ‘Lee‘;
}
function Desk()
{
this.age=100; //被继承的函数叫做子类型(子类,派生类)
}
function Table()
{
this.level = ‘AAAAAA‘;
}
//通过原型链继承,超类型实例化后的对象实例,赋值给子类型的原型属性
//new Box()会将Box构造函数的信息和原型里面的信息都交给Desk
//Desk的原型,得到的是Box的构造+原型里的信息
Desk.prototype = new Box();
var desk = new Desk();
alert(desk.age); //=> 100
alert(desk.name); //=> Lee
//2> 使用对象冒充继承
function Box(name ,age)
{
this.name =name;
this.age = age;
this.family=[‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘]; //引用类型,放在构造里面就不会被共享
}
//Box.prototype.family = ‘家庭‘;
function Desk(name ,age)
{
Box.call(this,name ,age) //对象冒充 ★只能继承构造里面的信息
}
var desk = new Desk(‘Lee‘ , 100);
alert(desk.family); =>‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘
desk.family.push(‘弟弟‘);
alert(desk.family); =>‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘ , ‘弟弟‘
var desk2= new Desk(‘Lee‘ , 100);
alert(desk2.family); =>‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘
----------------------------------------------------------------------------
//3> 原型链继承
function Box(name ,age)
{
this.name =name;
this.age = age;
this.family=[‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘];
}
Box.prototype.run =function()
{
return this.name + this.age +‘运行中‘;
}
//构造函数里的方法,放在构造函数里,每次实例化,都会分配一个内存地址,浪费,所以最好放在原型上
function Desk(name , age)
{
Box.call(this , name , age);
}
Desk.prototype=new Box(); // Desk的原型 继承了 Box的实例
var desk =new Desk(‘VVV‘ , 200);
alert(desk.run());
---------------扩展---------------------
//4> 原型式继承
//临时中转函数
function obj(o) //o表示将要传递进入的一个对象
{
function F(){}; //F构造是一个临时新建的对象,用来存储传递过来的对象
F.prototype =o; //将o对象实例赋值给F构造的原型对象
return new F(); //最后返回这个得到传递过来对象的对象实例
}
//F.prototype=o 其实就相当于 Desk.prototype = new Box();
//这是字面量的声明方式,相当于var box =new Box();
var box ={
name:‘Lee‘,
age:100,
family:[‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘]
};
//box1就等于new F();
var box1 =obj(box);
alert(box1.name); //‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘
alert(box1.family);
box1.family.push(‘弟弟‘); //‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘ ,‘弟弟‘
alert(box1.family);
var box2=obj(box);
alert(box1.family); //‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘ ,‘弟弟‘ [引用类型的属性共享了]
//5> 寄生式继承 = 原型式 +工厂模式
//临时中转函数
function obj(o)
{
function F(){};
F.prototype =o;
return new F();
}
//寄生函数
function create(o)
{
var f=obj(o);
f.run =function()
{
return this.name+‘方法‘;
}
return f;
}
var box ={
name:‘Lee‘,
age:100,
family:[‘哥哥‘ , ‘姐姐‘ , ‘妹妹‘]
};
var box1 = create(box);
alert(box1.run());
//寄生组合继承
//临时中转函数
function obj(o)
{
function F(){};
F.prototype =o;
return new F();
}
function create(box , desk)
{
var f=obj(box.prototype);
f.constructor =desk; //调整指针
desk.prototype=f;
}
function Box(name , age)
{
this.name = name;
this.age =age;
}
Box.prototype.run =function()
{
return this.name +this.age+‘运行中‘;
}
function Desk(name , age)
{
Box.call(this, name , age); //对象冒充
}
//通过寄生组合继承来实现继承
create(Box , Desk); //这句用来替代Desk.prototype =new Box();
var box1 = new Box(‘vvv‘ ,500);
alert(box1.run());
alert(box1.constructor);
var desk = new Desk(‘Lee‘ , 100);
alert(desk.run());
alert(desk.constructor);
javascript面向对象和原型