首页 技术 正文
技术 2022年11月21日
0 收藏 876 点赞 3,057 浏览 7526 个字

ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。
var box = new Object();
box.name = ‘Lee’;
box.age = 100;
box.run = function()
{
return this.name + this.age + ‘运行中…’; //this表示当前作用域下的对象,即new Object()实例化出来的那个对象,this要放在一个作用域下。比如box.run(){}。
}
alert(box.run());

alert(this.name); //这里的this 代表window

工厂模式 解决了重复实例化的问题,但是无法识别对象
function createObject(name,age)
{
var obj = new Object(); //创建对象
obj.name = name; //添加属性
obj.age = age;
obj.run = function(){
return this.name + this.age + ‘运行中…’;
};
return obj; //返回对象引用
}

var box1 = createObject(‘Lee’,100);
var box2 = createObject(‘Jack’,200);
alert(box1.run());
alert(box2.run());

alert(typeof box1);
alert(typeof box2);

构造函数创建对象
function Box(name,age){ //创建一个对象,所有构造函数的对象其实就是Object
this.name = name; //添加一个属性
this.age = age;
this.run = function(){ //添加一个方法
return this.name + this.age + ‘运行中…’;
};
};
function Desk(name,age){ //创建一个对象,所有构造函数的对象其实就是Object
this.name = name; //添加一个属性
this.age = age;
this.run = function(){ //添加一个方法
return this.name + this.age + ‘运行中…’;
};
};
//1.构造函数没有new Object,但它后台会自动var obj = new Object
//2.this就相当于obj
//3.构造函数不需要返回对象引用,它是后台自动返回的

//1.构造函数也是函数,但函数名第一个字母大写
//2.必须new构造函数名();new Box(),而这个Box第一个字母也是大写的。
//3.必须使用new运算符。
var box1 = new Box(‘Lee’,100);
var box2 = new Box(‘Jack’,200);
var box3 = new Desk(‘kkk’,500);
alert(box1.run());
alert(box2.run());
alert(box1 instanceof Box);
alert(box2 instanceof Box);
alert(box3 instanceof Desk);

原型
function Box(){} //构造函数函数体内什么都没有,这里如果有,叫做实例属性,实例方法
Box.prototype.name = ‘Lee’; //原型属性
Box.prototype.age = 100; //原型属性
Box.prototype.run = function(){ //原型方法
return this.name + this.age + ‘运行中…’;
};
var box1 = new Box();
var box2 = new Box();
alert(box1.name);
alert(box1.run());

//如果是实例方法,不同的实例化,它们的方法地址是不一样的,是唯一的。
//如果是原型方法,那么它们的地址是共享的。
//alert(box1.run == box2.run);  //地址共享,因为box1和box2的run方法都属于Box的原型方法
//alert(box1.prototype); //这个属性是一个对象,访问不到
//alert(box1.__proto__); //这个属性是一个指针指向prototype原型对象,IE浏览器不支持这个属性,打印不出来
//alert(box1.constructor); //构造属性,可以获取构造函数本身。作用是被原型指针定位,然后得到构造函数本身。其实就是对象实例对应的原型对象的作用。

//判断一个对象实例(对象引用)是不是指向了原型对象,基本上,只要实例化,他自动指向的。
//alert(Box.prototype.isPrototypeOf(box1));

//var obj = new Object();
//alert(Object.prototype.isPrototypeOf(obj));

//原型模式的执行流程
//1.先查找构造函数实例里的属性或方法,如果有,立刻返回;
//2.如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回。
//box1.name = ‘Jack’; //实例属性,并没有重写原型属性,就近原则
//alert(box1.name);
//alert(box2.name); //实例属性不会共享,所以box2访问不到实例属性,只能访问原型属性
//delete box1.name; //删除实例中的属性
//delete Box.prototype.name; //删除原型中的属性
//Box.prototype.name = ‘KK’; //覆盖原型中的属性
//alert(box1.name);

//box1.name = ‘KAC’
//alert(box1.hasOwnProperty(‘name’)); //判断实例中是否存在指定属性
//alert(‘name’ in box1); //不管实例属性或者原型属性是否存在,只要有就返回true

//判断只有原型中存在属性
//function isProperty(object,property){
//return !object.hasOwnProperty(property) && (property in object)
//}
//alert(isProperty(box1,’name’));

function Box(){};
var box = new Box();
alert(box.prototype); //使用对象实例无法访问到prototype
alert(box.__proto__); //使用对象实例访问prototype的指针
alert(Box.prototype); //使用构造函数名(对象名)访问prototype

//使用字面量的方式创建原型对象
function Box(){};
//这里{}就是对象,是Object,new Object就相当于{}
Box.prototype = {
constructor:Box, //强制指向Box
name:’Lee’,
age:100,
run:function(){
return this.name + this.age + ‘运行中…’;
}
};
//使用字面量的方式创建的原型对象会导致constructor指向Object而不是Box
字面量方式创建原型对象的constructor之所以会指向Object是因为Box.prototype={};
这种写法其实就是创建了一个新对象。而每创建一个函数,就会同时创建它的prototype,
这个对象也会自动获取constructor属性。所以,新对象的constructor重写了Box原来的constructor
因此会指向新对象,而新对象没有指定构造函数,那么就是指向Object。

//重写了原型对象
Box.prototype = {
age:200; //这里不会保留之前原型的任何信息了。把原来的原型对象和构造函数对象实例之前的关系切断了。
}
var box = new Box();
//alert(box.constructor == Box);
alert(box.age);

//数组排序
var box = [5,1,6,9,3,5,8,1];
alert(box.sort());

//查看sort是否是Array原型对象里的方法
alert(Array.prototype.sort);
//查看substring是否是String原型对象里的方法
alert(String.prototype.substring);

//内置引用类型的功能扩展
String.prototype.addstring = function(){
return this + ‘,被添加了!’;
};
var box = ‘Lee’;
alert(box.addstring());

//原型缺点
function Box(){}
Box.prototype={
constructor:Box,
name:’Lee’,
age:100,
family:[‘gege’,’jiejie’,’meimei’],
run:function(){
return this.name + this.age + ‘运行中…’
}
};
var box1 = new Box();
alert(box1.family);
box1.family.push(‘didi’); //在第一个实例修改后引用类型,保持了共享
alert(box1.family);
var box2 = new Box();
alert(box2.family); //共享了box1添加后的引用类型的原型

//为了解决构造传参和共享问题,可以组合构造函数+原型模式
function Box(name,age){
this.name = name;
this.age = age;
this.family = [‘gege’,’jiejie’,’meimei’];
}
Box.prototype = {
constructor:Box,
run:function(){
return this.name + this.age + ‘运行中…’;
}
};
var box1 = new Box(‘Kee’,100);
alert(box1.family);
box1.family.push(‘didi’);
alert(box1.family);
var box2 = new Box(‘lee’,200);
alert(box2.family); //引用类型没有使用原型,所以没有共享

//动态原型模式,可以将原型封装到构造函数里。封装性更好
function Box(name,age){
this.name = name;
this.age = age;
this.family = [‘gege’,’jiejie’,’meimei’];

if(typeof this.run != ‘function’){ //判断this.run是否存在
//alert(‘KS’)
Box.prototype.run = function(){
return this.name + this.age + ‘运行中…’;
};
//alert(‘JS’);
}
}
//原型的初始化,只要第一次初始化就可以了,没必要每次构造函数实例化的时候都初始化
var box1 = new Box(‘Kee’,100);
var box2 = new Box(‘lee’,200);

//寄生构造函数 工厂模式+构造函数
function Box(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age + ‘运行中…’;
};
return obj;
}
var box1 = new Box(‘Lee’,100);
alert(box1.run());
var box2 = new Box(‘Jack’,200);
alert(box2.run());

//稳妥构造函数
function Box(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age + ‘运行中…’;
};
return obj;
}
var box1 = Box(‘Lee’,100);
alert(box1.run());
var box2 = Box(‘Jack’,200);
alert(box2.run());

//继承,通过原型链实现
function Box(){ //被继承的函数叫做超类型(父类,基类)
this.name = ‘Lee’;
}
Box.prototype.name = ‘Jack’;
function Desk(){ //继承的函数叫做子类型(子类,派生类)
this.age = 100;
}
function Table(){
this.level = ‘AAAAAA’;
}
//通过原型链继承,超类型实例化后的对象实例,赋值给予类型的原型属性
//new Box()会将Box构造里的信息和原型里的信息都交给Desk
//Desk的原型,得到的是Box的构造+原型里的信息
Desk.prototype = new Box(); //通过原型链继承
Table.prototype = new Desk();
var desk = new Desk();
var table = new Table();
alert(desk.age);
alert(desk.name); //就近原则,实例里有,就返回,没有就去原型查找
alert(table.level);
//子类型从属于自己或者其他的超类型
alert(desk instanceof Desk);
alert(desk instanceof Box);
alert(box instanceof Desk);

//使用对象冒充继承
function Box(name,age){
this.name = name;
this.age = age;
this.family = [‘GEGE’,’JIEJIE’,’MEIMEI’]; //引用类型,放在构造里就不会被共享
}
Box.prototype.family = ‘jiating’;
function Desk(name,age){
Box.call(this,name,age) //对象冒充,只能继承构造里的信息
}
var desk = new Desk(‘Lee’,100);
alert(desk.name);
alert(desk.family);

//原型链+借用构造函数的模式,这种模式称为组合继承,解决了复用的问题
function Box(name,age){
this.name = name;
this.age = age;
this.family = [‘GEGE’,’JIEJIE’,’MEIMEI’];
}
Box.prototype.run = function(){
return this.name + this.age + ‘运行中…’;
}
//构造函数里的方法,放在构造函数里,每次实例化,都会分配一个内存地址,浪费空间.最好放在原型里,保证多次实例化只有一个地址
function Desk(name,age){
Box.call(this,name,age) //对象冒充
}
Desk.prototype = new Box(); //原型链继承
var desk = new Desk(‘Lee’,100);
alert(desk.run());

//原型式继承:这种继承借助原型并基于已有的对象创建新对象,同时还不会因此创建自定义类型。
//临时中转函数
function obj(o){ //o表示将要传递进入的一个对象
function F(){} //F构造是一个临时新建的对象,用来存储传递过来的对象
F.prototype = o; //将o对象实例赋值给F构造的原型对象
return new F(); //最后返回这个得到传递过来对象的对象实例
}
//F.prototype = 0其实就相当于Desk.prototype = new Box();
//这是字面量的声明方式,相当于var box = new Box();
var box = {
name:’Lee’,
age:100,
family:[‘gege’,’jiejie’,’meimei’]
};
//box1就等于new F();
var box1 = obj(box);
//alert(box1.name);
alert(box1.family);
box1.family.push(‘didi’);
alert(box1.family);
var box2 = obj(box);
alert(box2.family); //引用类型的属性共享了

//寄生式继承 = 原型式+工厂模式
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:[‘gege’,’jiejie’,’meimei’]
};
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 + ‘ssssss’;
}
function Desk(name,age){
Box.call(this,name,age); //对象冒充
}
//通过寄生组合继承来实现继承
create(Box,Desk); //这个用来替代Desk.prototype = new Box();
var desk = new Desk(‘Lee’,100);
alert(desk.run());
alert(desk.constructor);

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,581
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918