Javascript学习笔记之函数篇(五) : 构造函数


Posted in Javascript onNovember 23, 2014

Javascript 中的构造函数与其他语言相比也是不同的。任何通过关键字 new 调用的函数都可以当做构造函数。
在构造函数体内,this 指向新创建的对象。如果构造函数体内没有显示的 return 表达式,那么我们就默认返回 this,也就是新建的对象。

function Foo() {

    this.bla = 1;

}

Foo.prototype.test = function() {

    console.log(this.bla);

};

var test = new Foo();

上面的代码将 Foo 作为构造函数进行调用,并将新建对象的原型(__proto__)指向了 Foo.prototype。
如果我们在构造函数内定义返回的 return 表达式,构造函数就会返回整个表达式,但这个返回表达式必须为一个对象。

function Bar() {

    return 2;

}

new Bar(); // a new object

function Test() {

    this.value = 2;

    return {

        foo: 1

    };

}

new Test(); // the returned object

如果 new 被省略,那么函数将不能返回一个新的对象。

function Foo() {

    this.bla = 1; // gets set on the global object

}

Foo(); // undefined

上面的例子可能在某些场景下也可以运行,但由于 Javascript 中 this 的工作机制,这里 this 将指向全局对象。

工厂模式

为了能够不使用关键字 new,构造函数将不得不显示返回一个值。

function Bar() {

    var value = 1;

    return {

        method: function() {

            return value;

        }

    }

}

Bar.prototype = {

    foo: function() {}

};

new Bar();

Bar();

上例中使不使用 new 来调用函数 Bar 达到的效果是一样的,将会返回一个新建的包含 method 方法的对象,这里实际上就是一个闭包。
这里需要注意一点,new Bar() 将不会返回 Bar.prototype,而是在 return 表达式内函数 method 的原型对象。
上例中,使用 new 与否在功能上是无差异的。

通过工厂模式创建新的对象

我们经常被提醒不要使用 new,因为一旦忘记了它的使用将导致错误。
为了创建一个对象,我们更愿意使用工厂模式并在工厂模式内构造一个新的对象。

function Foo() {

    var obj = {};

    obj.value = 'blub';
    var private = 2;

    obj.someMethod = function(value) {

        this.value = value;

    }
    obj.getPrivate = function() {

        return private;

    }

    return obj;

}

尽管上例代码比使用 new 时更不容易出错,而且在使用私有变量时将更加方便,但同时也有一些不好的地方:

因为不能共享原型对象,所以需要更多的内存。
为了实现继承,工厂模式需要拷贝另一个对象的所有方法或者将其作为新对象的原型。
放弃原型链只是为了避免使用 new,这似乎与 Javascript 语言的精神相悖。

总结

尽管使用 new 可能比较容易产生错误,但这并不能成为放弃使用原型链的原因。至于最后采取哪种方式,这需要根据应用的需求而定。最好的方式就是选择一种风格并坚持下去。

简单的说构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象。

Javascript 相关文章推荐
Js获取事件对象代码
Aug 05 Javascript
js 求时间差的实现代码
Apr 26 Javascript
Bootstrap表格和栅格分页实例详解
May 20 Javascript
Angular.js基础学习之初始化
Mar 10 Javascript
vue单页应用中如何使用jquery的方法示例
Jul 27 jQuery
jquery+css实现下拉列表功能
Sep 03 jQuery
用jquery获取select标签中选中的option值及文本的示例
Jan 25 jQuery
详解React中setState回调函数
Jun 14 Javascript
深入了解Hybrid App技术的相关知识
Jul 17 Javascript
使用layui前端框架弹出form表单以及提交的示例
Oct 25 Javascript
element-ui table组件如何使用render属性的实现
Nov 04 Javascript
基于JavaScript实现省市联动效果
Jun 22 Javascript
Javascript学习笔记之函数篇(四):arguments 对象
Nov 23 #Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 #Javascript
js实例属性和原型属性示例详解
Nov 23 #Javascript
JS常用函数使用指南
Nov 23 #Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
Nov 23 #Javascript
理解jQuery stop()方法
Nov 21 #Javascript
JS中三目运算符和if else的区别分析与示例
Nov 21 #Javascript
You might like
2020年4月新番动漫目录 官方宣布4月播出的作品一览
2020/03/08 日漫
PHP集成FCK的函数代码
2008/09/27 PHP
php获取文件大小的方法
2014/02/26 PHP
PHP购物车类Cart.class.php定义与用法示例
2016/07/20 PHP
浅析Laravel5中队列的配置及使用
2016/08/04 PHP
CI框架实现优化文件上传及多文件上传的方法
2017/01/04 PHP
PHP利用Mysql锁解决高并发的方法
2018/09/04 PHP
jquery实现动态改变div宽度和高度
2015/05/08 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
jquery表单插件form使用方法详解
2017/01/20 Javascript
原生JS实现九宫格抽奖效果
2017/04/01 Javascript
webpack学习笔记之优化缓存、合并、懒加载
2017/08/24 Javascript
利用百度地图API获取当前位置信息的实例
2017/11/06 Javascript
利用原生的JavaScript实现简单拼图游戏
2018/11/18 Javascript
layui 实现二级弹窗弹出之后 关闭一级弹窗的方法
2019/09/18 Javascript
vue实现商城秒杀倒计时功能
2019/12/12 Javascript
在windows下快速搭建web.py开发框架方法
2016/04/22 Python
Python实现比较扑克牌大小程序代码示例
2017/12/06 Python
numpy自动生成数组详解
2017/12/15 Python
Python实现将照片变成卡通图片的方法【基于opencv】
2018/01/17 Python
python3 读取Excel表格中的数据
2018/10/16 Python
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
2020/01/21 Python
python pandas.DataFrame.loc函数使用详解
2020/03/26 Python
Python3爬虫关于代理池的维护详解
2020/07/30 Python
python实现梯度下降算法的实例详解
2020/08/17 Python
雅诗兰黛美国官网:Estee Lauder美国
2016/07/21 全球购物
FitFlop澳大利亚官网:英国符合人体工学的鞋类品牌
2017/06/05 全球购物
学习委员自我鉴定
2014/01/13 职场文书
《月光启蒙》教学反思
2014/03/01 职场文书
2014年食堂工作总结
2014/11/20 职场文书
2014年林业工作总结
2014/12/05 职场文书
校园广播站开场白
2015/06/01 职场文书
5分钟教你docker安装启动redis全教程(全新方式)
2021/05/29 Redis
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js
Java8利用Stream对列表进行去除重复的方法详解
2022/04/14 Java/Android