700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > javascript --- 设计模式之构造函数模式

javascript --- 设计模式之构造函数模式

时间:2020-05-26 05:27:13

相关推荐

javascript --- 设计模式之构造函数模式

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 =newher('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;

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

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。