基本用法

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.output= function () {
return this.model + "走了" + this.miles + "公里";
};
} var tom= new Car("大叔", 2009, 20000);
var dudu= new Car("Dudu", 2010, 5000); console.log(tom.output());
console.log(dudu.output());

问题是output()在每次创建对象的时候都重新定义了,没有共享。

可以用如下方式:

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.output= formatCar;
} function formatCar() {
return this.model + "走了" + this.miles + "公里";
}

更好的方式,使用原型继承output方法:

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
} /*
注意:这里我们使用了Object.prototype.方法名,而不是Object.prototype
主要是用来避免重写定义原型prototype对象
*/
Car.prototype.output= function () {
return this.model + "走了" + this.miles + "公里";
}; var tom = new Car("大叔", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000); console.log(tom.output());
console.log(dudu.output());

除了使用new,可以作为函数调用、call方式

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
// 自定义一个output输出内容
this.output = function () {
return this.model + "走了" + this.miles + "公里";
}
} //方法1:作为函数调用
Car("大叔", 2009, 20000); //添加到window对象上
console.log(window.output()); //方法2:在另外一个对象的作用域内调用
var o = new Object();
Car.call(o, "Dudu", 2010, 5000);
console.log(o.output());

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

//作为函数调用
var tom = Car("大叔", 2009, 20000);
console.log(typeof tom); // "undefined"
console.log(window.output()); // "大叔走了20000公里"

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

//使用new 关键字
var tom = new Car("大叔", 2009, 20000);
console.log(typeof tom); // "object"
console.log(tom.output()); // "大叔走了20000公里"

使用instanceof来强制使用new

function Car(model, year, miles) {
if (!(this instanceof Car)) {
return new Car(model, year, miles);
}
this.model = model;
this.year = year;
this.miles = miles;
this.output = function () {
return this.model + "走了" + this.miles + "公里";
}
} var tom = new Car("大叔", 2009, 20000);
var dudu = Car("Dudu", 2010, 5000); console.log(typeof tom); // "object"
console.log(tom.output()); // "大叔走了20000公里"
console.log(typeof dudu); // "object"
console.log(dudu.output()); // "Dudu走了5000公里"

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

参考地址

[JS设计模式]:构造函数模式(2)的更多相关文章

  1. [js]js设计模式-构造函数模式

    构造函数模式 function WriteJsPerson(name,age) { this.name=name; //不用手动创建obj this.age = age; this.writeJs=f ...

  2. js设计模式--单体模式

    GOF里的23种设计模式, 也是在软件开发中早就存在并反复使用的模式. 如果程序员没有明确意识到他使用过某些模式, 那么下次他也许会错过更合适的设计 (这段话来自<松本行弘的程序世界>). ...

  3. js设计模式--迭代器模式

    迭代器模式: 迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示.js中我们经常会封装一个each函数用来实现迭代器. 理解的意思:提供一个方法,去把对象的每一项按 ...

  4. [转]js设计模式-策略模式

    在程序设计中,常常遇到类似的情况,要实现某一个功能有多种方案可以选择.比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是本文 ...

  5. 如何做JS 单体模式的设计---->>js设计模式<<-------单体模式

    1. 单体模式是js中最基本 单最有用的模式之一,非常常用. 单体模式的基本结构如下: var Person = { name: 'lilu', age:', sayHi: function(){ a ...

  6. js设计模式--工厂模式

    工厂模式: 工厂模式的目的是为了创建对象,它经常是在类和类的方法中实现.简单的工厂模式是由一个方法来决定到底要创建哪类的实例,这些实例经常拥有相同的接口,这种模式在所实例化的类型在编译期并不确定,而是 ...

  7. JS设计模式——工厂模式详解

    它的领域中同其它模式的不同之处在于它并没有明确要求我们使用一个构造器.取而代之,一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型. 简单工厂模式:使用一个类(通常 ...

  8. [js]js设计模式-原型模式

    构造函数模型- 对象的属性和方法每人一份 function createJs(name, age) { this.name = name; this.age = age; this.writeJs = ...

  9. 浅谈js设计模式 — 命令模式

    命令模式最常见的应用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么.此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦 ...

  10. js设计模式-命令模式

    命令模式是一种组织型模式,主要用在把调用对象(用户界面.API和代理等)与实现操作的对象隔离开.也就是说 ,凡是两个对象间的互动方式需要更高的模块化程度时都可以用到这种模式. 命令模式的好处:1.提高 ...

随机推荐

  1. Java作业五(2017-10-15)

    /*3-6.程序员;龚猛*/ 1 package zhenshu; import java.util.Scanner; public class text { public static void m ...

  2. [SQL]LeetCode196. 删除重复的电子邮箱 | Delete Duplicate Emails

    Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique ...

  3. [Swift]LeetCode952. 按公因数计算最大组件大小 | Largest Component Size by Common Factor

    Given a non-empty array of unique positive integers A, consider the following graph: There are A.len ...

  4. ActiveMQ嵌入Tomcat

    在一些项目中,单独开启一个ActiveMQ,对于项目实施来说有时略显繁琐.所以我们将ActiveMQ内嵌到Tomcat,Tomcat启动同时就顺带启动了ActiveMQ.由此我们需要掌握三个个重要的知 ...

  5. python高级-装饰器(19)

    一.什么是闭包 先看一个例子: #定义一个函数 def test(number): #在函数内部在定义一个函数,并且这个函数用到外围函数的变量 #那么将这个函数及用到的一些变量称之为闭包 def te ...

  6. JavaScript基础之值传递和引用传递

    js的值传递和引用(地址)传递 首先总述一下:js的5种基本数据类型 number,string,null,undefined,boolean 在赋值传递时是值传递,js的引用数据类型(object, ...

  7. linux静态ip的设置

    我们经常使用虚拟机安装(我使用的linux版本是CentOS6.5),然后配置服务器的web环境,用于程序的调试.默认情况下,linux使用动态ip,每次启动linux时,它的ip地址都有可能发生变化 ...

  8. 在asp.net web api 2 (ioc autofac) 使用 Serilog 记录日志

    Serilog是.net里面非常不错的记录日志的库,另外一个我认为比较好的Log库是NLog. 在我个人的asp.net web api 2 基础框架(Github地址)里,我原来使用的是NLog,但 ...

  9. github pages绑定域名

    网上很多人问 github 绑定域名要不要备案,很多人的回答是: 国内主机需要备案,国外主机不用 这个说法是没错的,但是却没有直接回答出 github pages 是否需要备案! 首先声明 githu ...

  10. android 工具库

    https://github.com/xybCoder/AndroidCommon android工具类集合