//工厂模式 //解决了重复实例化,但是有识别问题 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 box = createObject(‘Lee‘, 100); //创建对象 var box1 = createObject(‘Jack‘, 200); alert(box.run()); //打印对象方法 alert(box1.run()); //*************************************************构造函数 //解决了重复实例化,解决识别问题,改良后的工厂方法 function Box(name, age){ //创建对象 this.name = name; //添加属性 this.age = age; this.run = function(){ return this.name + this.age + ‘运行中...‘; }; } function Desk(name, age){ //创建对象 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 box = new Box(‘Lee‘, 100); //实例化 var box1 = new Box(‘Jack‘, 200); var box2 = new Desk(‘kkk‘, 300); // alert(box.run()); //打印对象方法 // alert(box1.run()); console.log(box instanceof Box); console.log(box1 instanceof Box); console.log(box2 instanceof Box); //可以识别 console.log(box2 instanceof Desk); //*************************************************对象冒充 function Box(name, age){ //创建对象 this.name = name; //添加属性 this.age = age; this.run = function(){ return this.name + this.age + ‘运行中...‘; }; } var o = new Object(); Box.call(o, ‘Lee‘, ‘100‘); //对象冒充 alert(o.run()); //**************************************************引用地址一致性,不好 //外部函数解决,不好 function Box(name, age){ //创建对象 this.name = name; //添加属性 this.age = age; this.run = run; } function run(){ //把构造函数内部方法通过全局来保证引用地址一致性 return this.name + this.age + ‘运行中...‘; } var box = new Box(‘Lee‘, 100); var box1 = new Box(‘Lee‘, 100); // alert(box.name == box1.name); // alert(box.age == box1.age); // alert(box.run() == box1.run()); // alert(box.run); //方法的引用地址 alert(box.run == box1.run); //因为比较他们实例化地址 alert(run()); //**************************************************原型模式方式,引用地址一致,好 function Box(){} //构造函数函数体内什么都没有,这里如果有,叫做实例属性,实例方法 Box.prototype.name = ‘Lee‘; //原型属性 __proto__ Box.prototype.age = 100; Box.prototype.run = function(){ //属性方法 return this.name + this.age + ‘运行中...‘; } var box = new Box(); box.name = ‘Jack‘; //实例属性,并没有重写原型属性 console.log(box.name); //就近原则,先查找实例属性和方法,没有在去找原型属性和方法 // console.log(box.hasOwnProperty(‘name‘)); //判断是否是实例属性 delete box.name; console.log(box.name); // delete Box.prototype.name; // Box.prototype.name = ‘kkk‘; alert(‘name‘ in box); //实例或原型都有就返回true var box1 = new Box(); // console.log(box1.name); //实例属性不会共享,所以box1访问不到box的实例属性 alert(isProperty(box1, ‘name‘)); // console.log(box.age); // console.log(box.run()); // console.log(box.run == box1.run); //true // console.log(box.prototype); //实例访问不到prototype,这个属性是对象,访问不到 // console.log(box.__proto__); //这个属性是指针,指向prototype圆形对象,ie不支持打印 //console.log(Box.prototype); //使用对象名访问prototype // console.log(box.constructor); //构造属性,可以获取构造函数本身Box() // //作用是被原型指针定位,然后得到构造函数本事 // //其实就是 对象实例 对应的 原型对象 的作用 // console.log(box1.name); //判断依个对象实例(对象引用)是否指向原型对象,基本上,只要实例化了,自动指向 // console.log(Box.prototype.isPrototypeOf(box)); // var obj = new Object(); // console.log(Box.prototype.isPrototypeOf(obj)); function isProperty(object, proterty){ return !object.hasOwnProperty(proterty) && (proterty in object); } //*************************************************** //字面量的方式创建原型对象,这里的{}就是对象,而且是Object, new Object() = {} function Box(){}; Box.prototype = { constructor : Box, //强制指向Box name : ‘Lee‘, age : 100, run : function(){ return this.name + this.age + ‘运行中...‘; } }; // var box = new Box(); // console.log(box.constructor); //Object Box.prototype = { age : 200 //这里不会保留之前原型的任何信息, } //把原来的原型对象和构造函数对象实例之前的关系切断了 var box = new Box(); console.log(box.name); // var box = [2,34,5,2,3,6,7,4,75]; // console.log(box.sort()); //查看sort是否是Array原型对象里的方法 // alert(Array.prototype.sort); // alert(String.prototype.substring); //内置引用类型的功能扩展 String.prototype.addstring = function(){ return this + ‘被添加的...‘; } var box = ‘Lee‘; alert(box.addstring()); function Box(){}; Box.prototype = { constructor : Box, //强制指向Box name : ‘Lee‘, age : 100, family : [‘哥哥‘, ‘姐姐‘, ‘妹妹‘], run : function(){ return this.name + this.age + ‘运行中...‘; } }; var box = new Box(); alert(box.family); box.family.push(‘弟弟‘); //在第一个实例修改后引用类型,保持了共享 alert(box.family); var box1 = new Box(); alert(box1.family); //共享了box添加后引用类型的原型 //组合构造函数 + 原型模式 function Box(name, age){ //保持独立的用构造函数 this.name = name; this.age = age; this.family = [‘哥哥‘, ‘姐姐‘, ‘妹妹‘]; } Box.prototype = { //保持共享的用原型 constructor : Box, run : function(){ return this.name + this.age + ‘运行中...‘; } } var box = new Box(‘Lee‘, 100); console.log(box.run()); alert(box.family); box.family.push(‘弟弟‘); //在第一个实例修改后引用类型,保持了共享 alert(box.family); var box1 = new Box(‘Jack‘, 200); console.log(box1.run()); alert(box1.family); //引用类型没有使用原型,所以没有共享 //动态原型模式 function Box(name, age){ //保持独立的用构造函数 this.name = name; this.age = age; this.family = [‘哥哥‘, ‘姐姐‘, ‘妹妹‘]; if(typeof this.run != ‘function‘){ //判断this.run是否存在,初始化一次 Box.prototype.run = function(){ return this.name + this.age + ‘运行中...‘; } } } //原型初始化,只要第一次初始化就可以了,没必要每次构造函数实例化的时候都初始化 var box = new Box(‘Lee‘, 100); console.log(box.run()); var box1 = new Box(‘Jack‘, 200); console.log(box1.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 box = new Box(‘Lee‘, 100); console.log(box.run()); var box1 = new Box(‘Jack‘, 200); console.log(box1.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 box = Box(‘Lee‘, 100); console.log(box.run()); //继承,通过原型链实现 function Box(){ //被继承的函数叫超类型(父类,基类) this.name = ‘Lee‘; } function Desk(){ //继承的函数叫做子类型(子类,派生类) this.age = 100; } function Table(){ this.level = ‘AAAAA‘; } //超类型实例化后的对象实例,赋值给子类型的原型属性 //new Box()会将Box构造里的信息和原型里的信息都交给Desk //Desk的原型,得到的是Box的构造+原型里的信息 Desk.prototype = new Box(); Table.prototype = new Desk(); var box = new Box(); alert(box.constructor); var desk = new Desk(); console.log(desk.age); console.log(desk.name); var table = new Table(); console.log(table.name); console.log(table.level); function Box(){ //被继承的函数叫超类型(父类,基类) this.name = ‘Lee‘; } Box.prototype.name = ‘Jack‘; function Desk(){ //继承的函数叫做子类型(子类,派生类) this.age = 100; } Desk.prototype = new Box(); var box = new Box(); var desk = new Desk(); console.log(desk.name); //就近原则,实例有就返回,没有就找原型 //子类型从属于自己或者他的超类型 console.log(desk instanceof Object); console.log(desk instanceof Desk); console.log(desk instanceof Box); console.log(box instanceof Desk); //对象冒充继承 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); console.log(desk.name); console.log(desk.family); 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); //对象冒充,只能继承构造里的信息 } var desk = new Desk(‘Lee‘, 100); console.log(desk.name); console.log(desk.family); console.log(desk.run()); //继承不到prototype var desk1 = new Desk(‘Lee‘, 100); //组合继承 原型链 + 借用构造函数 //解决1构造传参,2原型链方法继承,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(); var desk = new Desk(‘Lee‘, 100); console.log(desk.name); console.log(desk.family); console.log(desk.run()); //继承不到prototype var desk1 = new Desk(‘Lee‘, 100); //原型式继承,问题:引用类型共享了 //临时中转函数 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 : [‘哥哥‘, ‘姐姐‘, ‘妹妹‘] }; //box1就等于new F(); var box = obj(box); console.log(box.name); console.log(box.family); box.family.push(‘弟弟‘); console.log(box.family); var box1 = obj(box); console.log(box.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 : [‘哥哥‘, ‘姐姐‘, ‘妹妹‘] }; var box = create(box); console.log(box.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; if(typeof this.run != ‘function‘){ //判断this.run是否存在,初始化一次 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 desk = new Desk(‘Lee‘, 100); alert(desk.name); console.log(desk.constructor); alert(desk.run());
时间: 2024-11-06 11:49:45