💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 面向对象 **创建多个类似对象的解决方案** ### 工厂模式 带参数的函数里面创建对象 ~~~ function box(a,b){ var obj=new Object(); //创建对象 obj.a=a; obj.b=b; obj.run=function(){ return this.a+this.b; } return obj; } var box1=box("田伟",100); //创建对象 var box2=box('111','222'); alert(box1.run()); ~~~ //识别 alert(box1 instanceof Object); 问题:多个对象无法区分是哪个函数创建的 ### 构造函数模式 ~~~ function Box(name,age){ //创建对象,首字母大写 //后台自动创建new Object(); this.name=name; this.age=age; this.run=function(){ return this.name+this.age; } } var box1=new Box("田伟",100); //对象实例化 var box2=new Box("田伟",100); //对象实例化 alert(box1.run()); ~~~ **好处:** 无需new Object(); 无需返回 //识别 alert(box1 instanceof Box); ### 对象冒充模式 在构造函数模式上,实例方式不同 ~~~ function Box(name,age){ //创建对象,首字母大写 //后台自动创建new Object(); this.name=name; this.age=age; //实例属性 this.run=function(){ //实例方法 return this.name+this.age; } } var o=new Object(); Box.call(o,"田伟",100); alert(o.run()); ~~~ * * * * * ## 原型 每个函数都一个prototype的原型属性,这个属性是对象。这个对象包含一系列共享属性和方法 函数默认生成__proto__的属性指针,指向prototype对象的属性constructor,起对象实例和原型对象对应的连接作用 ~~~ function Box(){}; //什么都不能有,有的话叫实例属性 Box.prototype.name="田伟"; Box.prototype.age=100; //原型属性 Box.prototype.run=function(){ //原型方法 return this.name=this.age; } var box1=new Box(); alert(box1.name); ~~~ 使用字面量方式创建原型对象,改造上面的例子 ~~~ function Box(){}; Box.prototype={ constructor:Box,//强制指向Box name:"田伟", age:100, run:function(){ return this.name+this.age; } } var box1=new Box(); alert(box1.name); ~~~ 如果原型里面有引用类型的属性,如数组,属性值实例化也会共享,无法独立,所以使用: ### 组合构造函数+原型模式 独立的部分用构造函数创建,共享的部分用原型创建 ~~~ function Box(name,age){ this.name=name; this.age=age; this.family=['姐姐','妹妹']; }; Box.prototype={ constructor:Box, run:function(){ return this.name+this.age; } } var box1=new Box("田伟",100); alert(box1.name); ~~~ 上面的例子没有封装,解决: ### 动态原型模式 把原型放到构造函数里面,但原型只应该初始化一次,if ~~~ 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; } } }; var box1=new Box("田伟",100); alert(box1.name); ~~~ * 每个实例方法,属性的地址是不一样的 * 原型方法,属性的地址是共享的 ![](https://box.kancloud.cn/ede2eb45160c1dc3bef1dc6273c6d1dc_447x372.png) ![](https://box.kancloud.cn/2fddb28f58b83794c4702382ded29a42_666x393.png) `alert(box1.__proto__);` 实例属性和原型属性都有值,优先调用实例属性,如下: ![](https://box.kancloud.cn/861a2c60252d368dc995ba6b8bb5ebec_695x418.png) 可以删除实例属性:delete box1.name; 删除原型属性:delete Box.prototype.name; * * * * * 基本类型也可以找出原型方法 alert(Array.prototype.sort); ## 继承 ~~~ function Box(){ this.name="tian"; } function Desk(){ this.age=100; } Desk.prototype=new Box(); //通过原型继承box的属性 var desk1=new Desk(); alert(desk1.name); ~~~ ![](https://box.kancloud.cn/3ba2ed322a88836e55d6c9b4b778a181_735x528.png)