JavaScript里,构造函数通常是认为用来实现实例的,JavaScript没有类的概念,但是有特殊的构造函数。通过new关键字来调用定义的否早函数,你可以告诉JavaScript你要创建一个新对象并且新对象的成员声明都是构造函数里定义的。在构造函数内部,this关键字引用的是新创建的对象。基本用法如下:

function her(name, sex, height){this.name = name;this.sex = sex;this.height = height;this.say = function(){return this.name + ' is a ' + this.sex + ' has ' + this.height;}
}
var she1 = new her('Anna', 'women', '170cm');
console.log(she1.say());  // 'Anna is a Women has 170cm'

  上面的例子是个非常简单的构造函数模式,但是有点小问题。首先是使用继承很麻烦了,其次output()在每次创建对象的时候都重新定义了,最好的方法是让所有Car类型的实例都共享这个output()方法,这样如果有大批量的实例的话,就会节约很多内存(这种情况在之前的文章里提到过了,可以看一下)。

解决这个问题,我们可以使用如下方式:

function her(name, sex, height){this.name = name;this.sex = sex;this.height = height;this.say = gaoHan;
}
function gaoHan(){return this.name + ' is a ' + this.sex + ' has ' + this.height;
}

这个方式虽然可用,但是我们有如下更好的方式。

JavaScript里函数有个原型属性叫prototype,当调用构造函数创建对象的时候,所有该构造函数原型的属性在新创建对象上都可用。按照这样,多个her对象实例可以共享同一个原型,我们再扩展一下上例的代码:

function her(name, sex, height){this.name = name;this.sex = sex;this.height = height;
}
/*注意:这里我们使用了Object.prototype.方法名,而不是Object.prototype主要是用来避免重写定义原型prototype对象*/her.prototype.say = function(){     return this.name + ' is a ' + this.sex + ' has ' + this.height;}
var she1 = new her('Anna', 'women', '170cm');
console.log(she1.say());  // 'Anna is a Women has 170cm'

这里,say()单实例可以在所有Car对象实例里共享使用。另外:我们推荐构造函数以大写字母开头,以便区分普通的函数。

只能用new吗?

function her(name, sex, height){this.name = name;this.sex = sex;this.height = height;this.say = function(){return this.name + ' is a ' + this.sex + ' has ' + this.height; } }
//方法1:作为函数调用 her('Anna', 'women', '170cm');
//添加到window对象上 console.log(window.say()); 

//方法2:在另外一个对象的作用域内调用 var o = new Object(); her.call(o, "Anna", "women", "170cm"); console.log(o.say()); 

该代码的方法1有点特殊,如果不适用new直接调用函数的话,this指向的是全局对象window,我们来验证一下:

// 作为函数调用
var she = her('Anna', 'women', '170cm');
console.log(typeof tom); // 'undefined'
console.log(window.say());

这时候对象tom是undefined,而window.output()会正确输出结果,而如果使用new关键字则没有这个问题,验证如下:

// 作为函数调用
var she = her('Anna', 'women', '170cm');
console.log(typeof tom); // 'undefined'
console.log(tom.say());

强制使用new!

上述的例子展示了不使用new的问题,那么我们有没有办法让构造函数强制使用new关键字呢,答案是肯定的,上代码:

function Her(name, sex, height){if( !(this instanceof her) ){return new Car(name, sexr, height);}this.name = name;this.year = year;this.height= height;this.say = function(){return this.name + ' is a ' + women + ' has ' + this.height;}
}var she1 = new her('Anna', 'women', '170cm');var she2 = her('Lous', 'women', '165cm');console.log(typeof she1); // object;console.log(typeof she2); // object;

通过判断this的instanceof是不是Car来决定返回new Car还是继续执行代码,如果使用的是new关键字,则(this instanceof Car)为真,会继续执行下面的参数赋值,如果没有用new,(this instanceof Car)就为假,就会重新new一个实例返回。

原始包装函数:

// 使用原始包装函数
var s = new String("my javascript");
var n = new Number(520);
var b = new Boolean(true);// 推荐这种
var s = "my javascript";
var n = 520;
var b = true;

推荐,只有在想保留数值状态的时候使用这些包装函数,关于区别可以参考下面的代码:

// 原始string
var greet = "Hello there";
// 使用split()方法分割
greet.split(' ')[0]; // "Hello"
// 给原始类型添加新属性不会报错
greet.smile = true;
// 单没法获取这个值(18章ECMAScript实现里我们讲了为什么)
console.log(typeof greet.smile); // "undefined"// 原始string
var greet = new String("Hello there");
// 使用split()方法分割
greet.split(' ')[0]; // "Hello"
// 给包装函数类型添加新属性不会报错
greet.smile = true;
// 可以正常访问新属性
console.log(typeof greet.smile); // "boolean"

本章主要讲解了构造函数模式的使用方法、调用方法以及new关键字的区别,希望大家在使用的时候有所注意。

转载于:https://www.cnblogs.com/beyond-succeed/p/5856646.html

javascript --- 设计模式之构造函数模式相关推荐

  1. JavaScript 设计模式之构造函数模式

    一.构造函数模式概念解读 1.构造函数模式概念文字解读 构造函数用于创建特定类型的对象--不仅声明了使用的对象,构造函数还可以接受参数以便第一次创建对象的时候设置对象的成员值.你可以自定义自己的构造函 ...

  2. JavaScript设计模式-享元模式

    JavaScript设计模式-享元模式 概念 例子 内部状态与外部状态 享元模式的通用结构 例子 总结 github仓库地址:点击 [设计模式例子](https://github.com/fanhua ...

  3. JavaScript设计模式--简单工厂模式例子---XHR工厂

    JavaScript设计模式--简单工厂模式例子---XHR工厂 第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方 ...

  4. Javascript 设计模式之代理模式【讲师辅导】-曾亮-专题视频课程

    Javascript 设计模式之代理模式[讲师辅导]-969人已学习 课程介绍         随着 javascript ES6/7 的发布,很多老版本的设计模式的实现,今天来看是错误的,将被彻底. ...

  5. Javascript 设计模式之外观模式【讲师辅导】-曾亮-专题视频课程

    Javascript 设计模式之外观模式[讲师辅导]-770人已学习 课程介绍         随着 javascript ES6/7 的发布,很多老版本的设计模式的实现,今天来看是错误的,将被彻底. ...

  6. JavaScript设计模式总结-组合模式

    使用场景 1.对象存在整体-部分的结构,如树.数组等: 2.使用者希望对数据结构中的所有对象统一处理. 需要注意的是 1.组合模式所谓的结构并非"继承",而是"包含&qu ...

  7. java 懒加载模式_JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

    我写的程序员面试系列文章 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Jav ...

  8. Javascript设计模式之——代理模式

    最近在读<javascript设计模式与开发实践>,在这里把文中的各种设计模式写出来,以便加深记忆,也可以分享给初学者.如果你不了解设计模式,那么强烈推荐你阅读一下这本书,相信它可以颠覆你 ...

  9. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索"为什么MVC不是一种设计模式呢?"其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composi ...

最新文章

  1. 机器学习中的优化算法!
  2. 一文详析国内读研和国外留学的差异以及优缺点
  3. 拒绝从入门到放弃_《Openstack 设计与实现》必读目录
  4. 一个函数两个return
  5. redis热点key解决方案_缓存穿透,缓存雪崩,4种解决方案分析
  6. mini_magick上传图片
  7. Linux内核启动过程和Bootloader(总述)
  8. 计算机前端学哪些好学,Web前端能干什么工作,好学吗
  9. 王坚数博会演讲实录:“计算经济”是社会发展的新动力
  10. Java设计模式-Builder生成器模式
  11. Whidbey——C#前瞻
  12. 基于windows的iOS自动化测试
  13. ios识别人脸自动拍照_iOS 相机流人脸识别(一)-人脸框检测(基于iOS原生)
  14. 计算机文化基础说课ppt,计算机文化基础说课 -_图文.ppt
  15. java modifier access_Java中的默认访问修饰符是什么? (What is the default access modifier in Java?)...
  16. 理解无线电波极化与天线极化
  17. Elasticsearch摄取节点(八)——数据解析处理器
  18. 归并排序及其优化(数组归并/链表归并,自顶向下/自底向上等)
  19. iOS 四舍五入保留两位小数
  20. 推荐一款超级好用的AI模型训练平台——Tesra超算网络!

热门文章

  1. JAVA类加载对字节码的处理_深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)...
  2. 〖Python接口自动化测试实战篇⑤〗- 接口自动化测试必备基础 - http协议
  3. vmware虚拟机查看宿主机ip(主机ip)
  4. spring的生命周期:init-method和destroy-method.(以及初始前后代理测试)
  5. python爬虫雪球现金流量表资产负债表字段表20230324
  6. 前端web学习 html入门
  7. 删除计算机其他用户名和密码是什么情况,电脑用户名怎么删除_电脑用户名怎么取消...
  8. echart图标渐变色
  9. Flutter开发:Gridview的使用
  10. 目标检测中背景建模方法总结